緩存一致性協(xié)議
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”
優(yōu)質(zhì)文章,第一時間送達(dá)
? 作者?|??rudynan
來源 |? urlify.cn/7Vbmia
為什么需要緩存一致性協(xié)議
多個線程并發(fā)訪問一個共享變量時,這些線程的執(zhí)行處理器上的高速緩存各自都會保留一份共享變量的副本,這帶來一個問題,一個處理器對共享變量進(jìn)行修改,其他處理器如何察覺到該更新并做出適當(dāng)反應(yīng),以確保后續(xù)處理器讀取到這個共享變量時可以讀取到這個更新.這就是緩存一致性問題,其本質(zhì)就是防止讀臟數(shù)據(jù)和讀取到更新的數(shù)據(jù)
什么是緩存一致性協(xié)議
MESI(Modified-Exclusive-Shared-Invalid)協(xié)議是一種廣為使用的緩存一致性協(xié)議,類似讀寫鎖 對于同一地址的讀內(nèi)存操作是并發(fā)的,針對同一地址的寫操作是獨(dú)占的,對弈內(nèi)存地址寫操作同一時間只能由一個處理器來執(zhí)行.
為了保持?jǐn)?shù)據(jù)的一致性,MESI將緩存條目的狀態(tài)劃分為Modified.Exclusive,Shared,Invalid
MESI協(xié)議中一個緩存條目的狀態(tài)Flag值分為一下4中
1. Invalid(無效的,記為I) 相應(yīng)緩存行中不包含任何內(nèi)存地址對應(yīng)的有效副本數(shù)據(jù),是緩存條目的初始狀態(tài)
2. Shared(共享的,記為S)緩存行中包含相應(yīng)內(nèi)存地址數(shù)據(jù)的副本,其他處理器高速緩存中也可能包含相應(yīng)地址內(nèi)存的副本,緩存行中的數(shù)據(jù)與內(nèi)存的一致
3. Exclusive(獨(dú)占的,記為E)緩存行獨(dú)占相應(yīng)內(nèi)存地址數(shù)據(jù)的副本,其他處理器高速緩存不包含相同的副本或者副本失效,緩存行中的數(shù)據(jù)與主內(nèi)存數(shù)據(jù)一致
4. Modified(更改過,記為M)相應(yīng)緩存行包含更新后的數(shù)據(jù),其他處理器相同tag的緩存行只有唯一的M狀態(tài),與主內(nèi)存的數(shù)據(jù)不一致
MESI定義了一組message用于協(xié)調(diào)各個處理器的讀寫內(nèi)存操作,處理器在執(zhí)行內(nèi)存的讀寫操作是,在必要的情況下會往bus中發(fā)送特定的請求消息,每個處理器攔截這些消息,在一定情況下往bus回復(fù)消息
1. Read 通知其他處理器和主內(nèi)存 準(zhǔn)備讀取某個內(nèi)存地址的消息
2. Read Response 返回被read請求讀取的消息,可能是處理器返回的也可能是內(nèi)存返回的
3. Invalidate 通知其他處理器刪除高速緩存中對應(yīng)tag的數(shù)據(jù)副本
4. Invalidate Acknowledge 回復(fù)已經(jīng)刪除了高速緩存上相應(yīng)tag的副本
5.Read Invalidate 通知其他處理器準(zhǔn)備更新一個數(shù)據(jù)請求其他處理器刪除其高速緩存中的數(shù)據(jù)副本,收到消息的處理器必須回復(fù)read Response,Invalidate Acknowledge
6. Writeback 消息包含需要寫入內(nèi)存的數(shù)據(jù)和內(nèi)存地址
緩存一致性協(xié)議能做什么
對讀操作的實現(xiàn)
processor0會根據(jù)A的內(nèi)存地址在高速緩存找到對應(yīng)的緩存條目,如果緩存的flag為M E 或是S,那么處理器可以直接從緩存條目中拿取數(shù)據(jù),不向總線發(fā)送消息,如果flag為I說明條目無效或者沒有,需要向總線中發(fā)送read消息,其他處理器或者內(nèi)存需要回復(fù)read response,processor0接收到read response消息會更新自己的緩存條目狀態(tài)設(shè)置為S
其他處理器高速緩存中的緩存條目如果不為I才回復(fù)消息,注意回復(fù)的是緩存行整塊數(shù)據(jù),如果flag為M會發(fā)message之前先往內(nèi)存中寫,然后flag的狀態(tài)改為S,如果flag狀態(tài)為I,read Response消息來自內(nèi)存
對寫操作的實現(xiàn)
processor0在往地址A寫數(shù)據(jù)的時候,必須先擁有該數(shù)據(jù)的所有權(quán),如果processor0高速緩存地址A的緩存條目flag為E 或 M,說明已經(jīng)獲取了所有權(quán),可以直接將數(shù)據(jù)寫入緩存行,flag為M,如果不為M E 則需要往消息總線發(fā)送Invalidate消息,接收到其他所有處理器回復(fù)的invalidate acknowledge消息后才獲得了數(shù)據(jù)的所有權(quán),才能更新數(shù)據(jù)到緩存行中
processor0找到的緩存條目如果為S,需要往總線中發(fā)送invalidate消息,等收到其他所有處理器返回的invalidate acknowledge時將緩存條目設(shè)置為E,此時獲得所有權(quán),然后將數(shù)據(jù)寫入緩存行,flag設(shè)為M
processor0找到的緩存條目如果為I,需要往總線發(fā)送read invalidate,等接受到read response和其他所有處理器的invalidate acknowledge之后將相應(yīng)緩存條目的狀態(tài)改為E,代表已經(jīng)獲得相應(yīng)數(shù)據(jù)的所有權(quán),寫入數(shù)據(jù)flag改為M
mesi能保證多線程對共享變量的可見性,可見性問題就要從寫緩沖器和無效化隊列的角度來解釋了
粉絲福利:108本java從入門到大神精選電子書領(lǐng)取
???
?長按上方鋒哥微信二維碼?2 秒 備注「1234」即可獲取資料以及 可以進(jìn)入java1234官方微信群
感謝點(diǎn)贊支持下哈?
