為什麼需要MESI快取一致性協議

2021-10-09 14:59:44 字數 1575 閱讀 3382

執行在不同cpu的2個執行緒,如何保證在修改相同變數的時候不發生衝突呢 ?

早期的做法加匯流排鎖:

匯流排鎖 – > 早期多核cup實現一致性的方式,給匯流排加互斥鎖,使另乙個核pending住。這樣通訊效率很低。

現在的做法使用快取一致性協議mesi modified,  exclusive, shared, invalid

如下圖:

有幾個名稱先介紹一下:

記憶體- 就是我們計算機的儲存條容量所代表的記憶體。當然記憶體的訪問速度大於硬碟速度。

快取- cache,是cup中的乙個儲存裝置,嵌入在cup中,訪問速度遠遠大於記憶體。一般分**快取,l3,l2,l1。 從3到1容量越來越小,速度越來越快。

匯流排- 用來連線cup和記憶體的裝置,記憶體和cup之間的資料交換必須通過匯流排。

暫存器- 用來儲存正在執行的指令**。

mesi 工作流程:

執行緒thread0 和執行緒thread1分別執行在不同的cpu core中。

當thread0 通過匯流排向記憶體獲取乙個資料時會拿到該資料所在的乙個快取行的資料(64k 前面介紹過), 該快取行包含變數x,這時候x的值為0. thread0將變數x載入到core0的快取中,這個時候會通過匯流排對該快取行新增乙個e(排他鎖)。

如果thread1也需要訪問變數x,thread1也會試圖通過匯流排來給該快取行加e鎖,但是發現該快取行已經被加鎖了。這個時候thread0會被通知到該操作,然後thread0和thread1 會把鎖變成s(共享鎖)。thread1繼續該快取行載入到core1中。

如果thread0執行語句x=1,試圖修改x的值,這時候thread0會試圖在該快取行修改狀態為m,並通知thread1該操作.

如果thread0的m鎖新增成功則會向thread1中傳送訊息,讓thread1中的變數x=0失效。這時t1中的變數變成了i(invalid)狀態。

如果thread0在給該快取行新增m鎖的同事,thread1也在試圖加m鎖,這個時候就會觸發匯流排裁決,匯流排根據cup時鐘,找出乙個最小提出加m鎖的執行緒,讓他加m鎖成功。

如果乙個變數大於乙個快取行直接公升級鎖為匯流排鎖。

volatile –> lock訊號->快取一致性協議。

mesi 不能保證原子性-因為乙個快取行的有可能包含幾個命令,其中乙個命令已經在暫存器裡面了,所以即使在快取中invalid了你的變數也有可能從暫存器中寫回初始化你的剛剛丟棄的變數。

thread0中變數x被修改後,不會馬上把修改後的值寫入到快取中, 而是把修改後的值寫如到乙個store buffer中,等到thread0傳送完訊息給thread1(invalid 變數x),並且thread1知道m鎖新增成功。然後再將store buffer中的counter寫入到快取行。

快取一致性協議MESI

處理器上有一套完整的協議,來保證cache一致性。比較經典的cache一致性協議當屬mesi協議,奔騰處理器有使用它,很多其他的處理器都是使用它的變種。單核cache中每個cache line有2個標誌 dirty和valid標誌,它們很好的描述了cache和memory 記憶體 之間的資料關係 資...

MESI(快取一致性協議)

現在的處理器都是多核處理器,並且每個核都帶有多個快取 指令快取和資料快取,見下圖 為什麼需要快取呢,這是因為cpu訪問記憶體的速度比較慢,所以在cpu和記憶體之間加了個快取以提高訪問速度。既然每個核都有快取,那麼假設兩個核或者多個核同時訪問同乙個變數時這些快取是如何進行同步的呢 快取細分為乙個個快取...

快取一致性協議(MESI協議)

大家都知道,計算機在執行程式時,每條指令都是在cpu中執行的,而執行指令過程中,勢必涉及到資料的讀取和寫入。由於程式執行過程中的臨時資料是存放在主存 物理記憶體 當中的,這時就存在乙個問題,由於cpu執行速度很快,而從記憶體讀取資料和向記憶體寫入資料的過程跟cpu執行指令的速度比起來要慢的多,因此如...