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