緩存一致性協(xié)議(MESI)
在目前主流的計(jì)算機(jī)中兼蕊,cpu執(zhí)行計(jì)算的主要流程如圖所示:
數(shù)據(jù)加載的流程如下:
1.將程序和數(shù)據(jù)從硬盤加載到內(nèi)存中
2.將程序和數(shù)據(jù)從內(nèi)存加載到緩存中(目前多三級緩存,數(shù)據(jù)加載順序:L3->L2->L1)
3.CPU將緩存中的數(shù)據(jù)加載到寄存器中映胁,并進(jìn)行運(yùn)算
4.CPU會將數(shù)據(jù)刷新回緩存房午,并在一定的時間周期之后刷新回內(nèi)存
緩存一致性協(xié)議發(fā)展背景
現(xiàn)在的CPU基本都是多核CPU,服務(wù)器更是提供了多CPU的支持,而每個核心也都有自己獨(dú)立的緩存昧互,當(dāng)多個核心同時操作多個線程對同一個數(shù)據(jù)進(jìn)行更新時挽铁,如果核心2在核心1還未將更新的數(shù)據(jù)刷回內(nèi)存之前讀取了數(shù)據(jù),并進(jìn)行操作敞掘,就會造成程序的執(zhí)行結(jié)果造成隨機(jī)性的影響叽掘,這對于我們來說是無法容忍的。
而總線加鎖是對整個內(nèi)存進(jìn)行加鎖玖雁,在一個核心對一個數(shù)據(jù)進(jìn)行修改的過程中更扁,其他的核心也無法修改內(nèi)存中的其他數(shù)據(jù),這樣對導(dǎo)致CPU處理性能嚴(yán)重下降赫冬。
緩存一致性協(xié)議提供了一種高效的內(nèi)存數(shù)據(jù)管理方案浓镜,它只會對單個緩存行(緩存行是緩存中數(shù)據(jù)存儲的基本單元)的數(shù)據(jù)進(jìn)行加鎖,不會影響到內(nèi)存中其他數(shù)據(jù)的讀寫劲厌。
因此膛薛,我們引入了緩存一致性協(xié)議來對內(nèi)存數(shù)據(jù)的讀寫進(jìn)行管理。
MESI協(xié)議
緩存一致性協(xié)議有MSI补鼻,MESI哄啄,MOSI,Synapse风范,F(xiàn)irefly及DragonProtocol等等咨跌,接下來我們主要介紹MESI協(xié)議。
MESI分別代表緩存行數(shù)據(jù)所處的四種狀態(tài)乌企,通過對這四種狀態(tài)的切換虑润,來達(dá)到對緩存數(shù)據(jù)進(jìn)行管理的目的。
| 狀態(tài) | 描述 | 監(jiān)聽任務(wù) |
| M 修改(Modify) | 該緩存行有效加酵,數(shù)據(jù)被修改了拳喻,和內(nèi)存中的數(shù)據(jù)不一致,數(shù)據(jù)只存在于本緩存行中 | 緩存行必須時刻監(jiān)聽所有試圖讀該緩存行相對應(yīng)的內(nèi)存的操作猪腕,其他緩存須在本緩存行寫回內(nèi)存并將狀態(tài)置為E之后才能操作該緩存行對應(yīng)的內(nèi)存數(shù)據(jù) |
| E 獨(dú)享冗澈、互斥(Exclusive) | 該緩存行有效,數(shù)據(jù)和內(nèi)存中的數(shù)據(jù)一致陋葡,數(shù)據(jù)只存在于本緩存行中 | 緩存行必須監(jiān)聽其他緩存讀主內(nèi)存中該緩存行相對應(yīng)的內(nèi)存的操作亚亲,一旦有這種操作,該緩存行需要變成S狀態(tài) |
| S 共享(Shared) | 該緩存行有效腐缤,數(shù)據(jù)和內(nèi)存中的數(shù)據(jù)一致捌归,數(shù)據(jù)同時存在于其他緩存中 | 緩存行必須監(jiān)聽其他緩存是該緩存行無效或者獨(dú)享該緩存行的請求,并將該緩存行置為I狀態(tài) |
| I 無效(Invalid) | 該緩存行數(shù)據(jù)無效 | 無 |
備注:
1.MESI協(xié)議只對匯編指令中執(zhí)行加鎖操作的變量有效岭粤,表現(xiàn)到j(luò)ava中為使用voliate關(guān)鍵字定義變量或使用加鎖操作
2.對于匯編指令中執(zhí)行加鎖操作的變量惜索,MESI協(xié)議在以下兩種情況中也會失效:
一、CPU不支持緩存一致性協(xié)議剃浇。
二巾兆、該變量超過一個緩存行的大小猎物,緩存一致性協(xié)議是針對單個緩存行進(jìn)行加鎖,此時角塑,緩存一致性協(xié)議無法再對該變量進(jìn)行加鎖蔫磨,只能改用總線加鎖的方式。
MESI工作原理:(此處統(tǒng)一默認(rèn)CPU為單核CPU圃伶,在多核CPU內(nèi)部執(zhí)行過程和一下流程一致)
1、CPU1從內(nèi)存中將變量a加載到緩存中留攒,并將變量a的狀態(tài)改為E(獨(dú)享)煤惩,并通過總線嗅探機(jī)制對內(nèi)存中變量a的操作進(jìn)行嗅探
2、此時炼邀,CPU2讀取變量a魄揉,總線嗅探機(jī)制會將CPU1中的變量a的狀態(tài)置為S(共享),并將變量a加載到CPU2的緩存中拭宁,狀態(tài)為S
3洛退、CPU1對變量a進(jìn)行修改操作,此時CPU1中的變量a會被置為M(修改)狀態(tài)杰标,而CPU2中的變量a會被通知兵怯,改為I(無效)狀態(tài),此時CPU2中的變量a做的任何修改都不會被寫回內(nèi)存中(高并發(fā)情況下可能出現(xiàn)兩個CPU同時修改變量a腔剂,并同時向總線發(fā)出將各自的緩存行更改為M狀態(tài)的情況媒区,此時總線會采用相應(yīng)的裁決機(jī)制進(jìn)行裁決,將其中一個置為M狀態(tài)掸犬,另一個置為I狀態(tài)袜漩,且I狀態(tài)的緩存行修改無效)
4、CPU1將修改后的數(shù)據(jù)寫回內(nèi)存湾碎,并將變量a置為E(獨(dú)占)狀態(tài)
5宙攻、此時,CPU2通過總線嗅探機(jī)制得知變量a已被修改介褥,會重新去內(nèi)存中加載變量a座掘,同時CPU1和CPU2中的變量a都改為S狀態(tài)
在上述過程第3步中,CPU2的變量a被置為I(無效)狀態(tài)后柔滔,只是保證變量a的修改不會被寫回內(nèi)存溢陪,但CPU2有可能會在CPU1將變量a置為E(獨(dú)占)狀態(tài)之前重新讀取內(nèi)存中的變量a,這個取決于匯編指令是否要求CPU2重新加載內(nèi)存睛廊。
總結(jié)
以上就是MESI的執(zhí)行原理嬉愧,MESI協(xié)議只能保證并發(fā)編程中的可見性,并未解決原子性和有序性的問題喉前,所以只靠MESI協(xié)議是無法完全解決多線程中的所有問題没酣。
————————————————
版權(quán)聲明:本文為CSDN博主「生煮雞蛋」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議卵迂,轉(zhuǎn)載請附上原文出處鏈接及本聲明裕便。
原文鏈接:https://blog.csdn.net/alignjava/article/details/99070162