MESI協(xié)議
MESI是Midified(已修改)莲蜘,Exclusive(獨占)阳欲,Shared(共享)眼姐,Invalidated(已失效)的縮寫诫惭,對應(yīng)Cache Line的四種狀態(tài)檩奠。
多核CPU的cache和內(nèi)存的構(gòu)成可以簡化為:每個CPU有自己的獨有的cache桩了,然后大家共享內(nèi)存,當每個CPU從cache中讀取數(shù)據(jù)時埠戳,如何保證所有cache和內(nèi)存中數(shù)據(jù)的一致性井誉,即使MESI協(xié)議要解決的問題。
四種狀態(tài)
【已修改】 即臟標記乞而,表示當前cache line中的數(shù)據(jù)已經(jīng)被更新過送悔,沒有被寫到內(nèi)存中∽δ#【已失效】狀態(tài)欠啤,表示這個cache line里的數(shù)據(jù)已經(jīng)失效,是不可以讀取的數(shù)據(jù)屋灌。
【獨占】和【共享】狀態(tài)都表示這個cache line中的數(shù)據(jù)是干凈的(即與內(nèi)存中的數(shù)據(jù)是一致的洁段,共享同時也表示與其他cpu cache中的數(shù)據(jù)是一致的)。
【獨占】是指當前這份數(shù)據(jù)只保存在當前cpu cache中共郭,其他cpu cache中沒有該數(shù)據(jù)(或者原本有的這份數(shù)據(jù)變成了已失效的)祠丝。所以這個時候更改獨占的數(shù)據(jù)就可以直接自由寫入疾呻,不需要通知其他的cpu cache(獨占的數(shù)據(jù)更改寫一次后,就會變成已修改的)写半。
而【獨占】狀態(tài)的數(shù)據(jù)岸蜗,如果有其他cpu從內(nèi)存讀取相同的數(shù)據(jù)到各自的cache,那么這個數(shù)據(jù)就會變成【共享】狀態(tài)叠蝇。
進一步的璃岳,【共享】狀態(tài)代表著相同一份數(shù)據(jù)在多個 CPU 的 Cache 里都有,所以當我們要更新 Cache 里面的數(shù)據(jù)的時候悔捶,不能直接修改铃慷,而是要先向所有的其他 CPU 核心廣播一個請求,要求先把其他核心的 Cache 中對應(yīng)的 Cache Line 標記為【無失效】狀態(tài)蜕该,然后再更新當前 Cache 里面的數(shù)據(jù)(這時數(shù)據(jù)的狀態(tài)就變?yōu)楠氄嫉睦绻瘢@時也會同時更新內(nèi)存中的數(shù)據(jù),下一次更改獨占的數(shù)據(jù)堂淡,就可以直接更改馋缅,不急于更新內(nèi)存的數(shù)據(jù))。
狀態(tài)轉(zhuǎn)換
MESI 協(xié)議的四種狀態(tài)之間的流轉(zhuǎn)過程淤齐,可以匯總成下面的表格:
其中股囊,本地讀寫是指當前cpu對于cache line的讀寫,遠程讀寫是指其他cpu讀寫相同的數(shù)據(jù)(對于當前cpu cache line的影響)更啄。
模擬工具
VivioJS MESI help (tcd.ie)
一個可以模擬MESI協(xié)議運行過程的網(wǎng)站稚疹,可以更好的理解協(xié)議的工作過程。
模擬的場景如下圖:
主要分為三個部分:
- 內(nèi)存:顯示的是內(nèi)存地址和數(shù)據(jù)
- CPU 緩存(Cache):顯示的是cache line中的變量數(shù)據(jù)祭务,以及MESI協(xié)議的狀態(tài)信息内狗,空白表示還沒有數(shù)據(jù)。
- CPU操作:通過點擊可以控制每個CPU對于每個數(shù)據(jù)的讀和寫操作义锥。
內(nèi)存和CPU 緩存之間有三個總線柳沙,分別是: - 數(shù)據(jù)總線:在CPU 緩存與內(nèi)存之間傳送需要處理或是需要儲存的數(shù)據(jù)。
- 地址總線:傳送在內(nèi)存之中儲存的數(shù)據(jù)的地址拌倍。
- shared:這個總線的作用是控制 Cache Line 的MESI狀態(tài)赂鲤。
具體過程大家可以在網(wǎng)站中去操作,很好理解柱恤。