12 張圖看懂 CPU 緩存一致性與 MESI 協(xié)議趟卸,真的一致嗎蹄葱?

前言

大家好,我是小彭锄列。

在上一篇文章里图云,我們聊到了 CPU 的三級(jí)緩存結(jié)構(gòu),提到 CPU 緩存就一定會(huì)聊到 CPU 的緩存一致性問題邻邮。那么竣况,什么是緩存一致性問題,CPU Cache 的讀取和寫入過程是如何執(zhí)行的筒严,MESI 緩存一致性協(xié)議又是什么丹泉?今天我們將圍繞這些問題展開。


學(xué)習(xí)路線圖:


1. 回顧 CPU 三級(jí)緩存結(jié)構(gòu)

由于 CPU 和內(nèi)存的速度差距太大鸭蛙,為了拉平兩者的速度差摹恨,現(xiàn)代計(jì)算機(jī)會(huì)在兩者之間插入一塊速度比內(nèi)存更快的高速緩存,CPU 緩存是分級(jí)的娶视,有 L1 / L2 / L3 三級(jí)緩存晒哄。

由于單核 CPU 的性能遇到瓶頸(主頻與功耗的矛盾),芯片廠商開始在 CPU 芯片里集成多個(gè) CPU 核心肪获,每個(gè)核心有各自的 L1 / L2 緩存寝凌。 其中 L1 / L2 緩存是核心獨(dú)占的,而 L3 緩存是多核心共享的孝赫。

基于局部性原理的應(yīng)用硫兰,CPU Cache 在讀取內(nèi)存數(shù)據(jù)時(shí),每次不會(huì)只讀一個(gè)字或一個(gè)字節(jié)寒锚,而是一塊塊地讀取劫映,每一小塊數(shù)據(jù)也叫 CPU 緩存行(CPU Cache Line)违孝。 為了標(biāo)識(shí) Cache 塊中的數(shù)據(jù)是否已經(jīng)從內(nèi)存中讀取,需要在 Cache 塊上增加一個(gè) 有效位(Valid bit)泳赋。

無論對(duì) Cache 數(shù)據(jù)檢查雌桑、讀取還是寫入,CPU 都需要知道訪問的內(nèi)存數(shù)據(jù)映射在 Cache 上的哪個(gè)位置祖今,這就是 Cache - 內(nèi)存地址映射問題校坑,映射方案有直接映射、全相聯(lián)映射和組相聯(lián)映射 3 種方案千诬。當(dāng)緩存塊滿或者內(nèi)存塊映射的緩存塊位置被占用時(shí)耍目,就需要使用 替換策略 將舊的 Cache 塊換出騰出空閑位置。

Cache - 內(nèi)存的直接映射方案

基于以上結(jié)構(gòu)徐绑,就會(huì)存在緩存一致性問題邪驮。


2. 什么是 CPU 緩存一致性問題?

CPU 緩存一致性(Cache Coherence)問題指 CPU Cache 與內(nèi)存的不一致性問題傲茄。事實(shí)上毅访, 在分析緩存一致性問題時(shí),考慮 L1 / L2 / L3 的多級(jí)緩存沒有意義盘榨, 所以我們提出緩存一致性抽象模型喻粹,只考慮核心獨(dú)占的緩存。

CPU 三級(jí)緩存與抽象模型

在單核 CPU 中草巡,只需要考慮 Cache 與內(nèi)存的一致性守呜。但是在多核 CPU 中,由于每個(gè)核心都有一份獨(dú)占的 Cache山憨,就會(huì)存在一個(gè)核心修改數(shù)據(jù)后查乒,兩個(gè)核心 Cache 數(shù)據(jù)不一致的問題。因此萍歉,我認(rèn)為 CPU 的緩存一致性問題應(yīng)該從 2 個(gè)維度理解:

  • 縱向:Cache 與內(nèi)存的一致性問題: 在修改 Cache 數(shù)據(jù)后,如何同步回內(nèi)存档桃?
  • 橫向:多核心 Cache 的一致性問題: 在一個(gè)核心修改 Cache 數(shù)據(jù)后枪孩,如何同步給其他核心 Cache?

接下來藻肄,我們將圍繞這兩個(gè)問題展開蔑舞。


3. 縱向:Cache 與內(nèi)存的一致性問題

3.1 CPU Cache 的讀取過程

這一節(jié),我們先來討論 Cache 的讀取過程嘹屯。事實(shí)上攻询,Cache 的讀取過程會(huì)受到 Cache 的寫入策略影響,我們暫且用相對(duì)簡(jiǎn)單的 “寫直達(dá)策略” 的讀取過程:

  • 1州弟、CPU 在訪問內(nèi)存地址時(shí)钧栖,會(huì)先檢查該地址的數(shù)據(jù)是否已經(jīng)加載到 Cache 中(Valid bit 是否為 1)低零;

  • 2、如果數(shù)據(jù)在 Cache 中拯杠,則直接讀取 Cache 塊上的字到 CPU 中掏婶;

  • 3、如果數(shù)據(jù)不在 Cache 中:

    • 3.1 如果 Cache 已裝滿或者 Cache 塊被占用潭陪,先執(zhí)行替換策略雄妥,騰出空閑位置;
    • 3.2 訪問內(nèi)存地址依溯,并將內(nèi)存地址所處的整個(gè)內(nèi)存塊寫入到映射的 Cache 塊中老厌;
    • 3.3 讀取 Cache 塊上的字到 CPU 中。

讀取過程(以寫直達(dá)策略)

但是黎炉,CPU 不僅會(huì)讀取 Cache 數(shù)據(jù)枝秤,還會(huì)修改 Cache 數(shù)據(jù),這就是第 1 個(gè)一致性問題 —— 在修改 Cache 數(shù)據(jù)后拜隧,如何同步回內(nèi)存宿百?有 2 種寫入策略:

3.2 寫直達(dá)策略(Write-Through)

寫直達(dá)策略是解決 Cache 與內(nèi)存一致性最簡(jiǎn)單直接的方式: 在每次寫入操作中,同時(shí)修改 Cache 數(shù)據(jù)和內(nèi)存數(shù)據(jù)洪添,始終保持 Cache 數(shù)據(jù)和內(nèi)存數(shù)據(jù)一致:

  • 1垦页、如果數(shù)據(jù)不在 Cache 中,則直接將數(shù)據(jù)寫入內(nèi)存干奢;
  • 2痊焊、如果數(shù)據(jù)已經(jīng)加載到 Cache 中,則不僅要將數(shù)據(jù)寫入 Cache忿峻,還要將數(shù)據(jù)寫入內(nèi)存薄啥。

寫直達(dá)的優(yōu)點(diǎn)和缺點(diǎn)都很明顯:

  • 優(yōu)點(diǎn): 每次讀取操作就是純粹的讀取,不涉及對(duì)內(nèi)存的寫入操作逛尚,讀取速度更快垄惧;
  • 缺點(diǎn): 每次寫入操作都需要同時(shí)寫入 Cache 和寫入內(nèi)存,在寫入操作上失去了 CPU 高速緩存的價(jià)值绰寞,需要花費(fèi)更多時(shí)間到逊。

寫直達(dá)策略

3.3 寫回策略(Write-Back)

既然寫直達(dá)策略在每次寫入操作都會(huì)寫內(nèi)存,那么有沒有什么辦法可以減少寫回內(nèi)存的次數(shù)呢滤钱?這就是寫回策略:

  • 1觉壶、寫回策略會(huì)在每個(gè) Cache 塊上增加一個(gè) “臟(Dirty)” 標(biāo)記位 ,當(dāng)一個(gè) Cache 被標(biāo)記為臟時(shí)件缸,說明它的數(shù)據(jù)與內(nèi)存數(shù)據(jù)是不一致的铜靶;

  • 2、在寫入操作時(shí)他炊,我們只需要修改 Cache 塊并將其標(biāo)記為臟争剿,而不需要寫入內(nèi)存已艰;

  • 3、那么秒梅,什么時(shí)候才將臟數(shù)據(jù)寫回內(nèi)存呢旗芬?—— 就發(fā)生在 Cache 塊被替換出去的時(shí)候:

    • 3.1 在寫入操作中,如果目標(biāo)內(nèi)存塊不在 Cache 中捆蜀,需要先將內(nèi)存塊數(shù)據(jù)讀取到 Cache 中疮丛。如果替換策略換出的舊 Cache 塊是臟的,就會(huì)觸發(fā)一次寫回內(nèi)存操作辆它;
    • 3.2 在讀取操作中誊薄,如果目標(biāo)內(nèi)存塊不在 Cache 中,且替換策略換出的舊 Cache 塊是臟的锰茉,就會(huì)觸發(fā)一次寫回內(nèi)存操作呢蔫;

可以看到,寫回策略只有當(dāng)一個(gè) Cache 數(shù)據(jù)將被替換出去時(shí)判斷數(shù)據(jù)的狀態(tài)飒筑,“清(未修改過片吊,數(shù)據(jù)與內(nèi)存一致)” 的 Cache 塊不需要寫回內(nèi)存,“臟” 的 Cache 塊才需要寫回內(nèi)存协屡。這個(gè)策略能夠減少寫回內(nèi)存的次數(shù)俏脊,性能會(huì)比寫直達(dá)更高。當(dāng)然肤晓,寫回策略在讀取的時(shí)候爷贫,有可能不是純粹的讀取了,因?yàn)檫€可能會(huì)觸發(fā)一次臟 Cache 塊的寫入补憾。

這里還有一個(gè)設(shè)計(jì): 在目標(biāo)內(nèi)存塊不在 Cache 中時(shí)漫萄,寫直達(dá)策略會(huì)直接寫入內(nèi)存。而寫回策略會(huì)先把數(shù)據(jù)讀取到 Cache 中再修改 Cache 數(shù)據(jù)盈匾,這似乎有點(diǎn)多余腾务?其實(shí)還是為了減少寫回內(nèi)存的次數(shù)。雖然在未命中時(shí)會(huì)增加一次讀取操作削饵,但后續(xù)重復(fù)的寫入都能命中緩存岩瘦。否則,只要一直不讀取數(shù)據(jù)葵孤,寫回策略的每次寫入操作還是需要寫入內(nèi)存担钮。

寫回策略

通過寫直達(dá)或?qū)懟夭呗猿髟覀円呀?jīng)能夠解決 “在修改 Cache 數(shù)據(jù)后尤仍,如何同步回內(nèi)存” 的問題。接下來狭姨,我們來討論第 2 個(gè)緩存一致性問題 —— 在一個(gè)核心修改 Cache 數(shù)據(jù)后宰啦,如何同步給其他核心 Cache苏遥?


4. 橫向:多核心 Cache 的一致性問題

在單核 CPU 中,我們通過寫直達(dá)策略或?qū)懟夭呗员3至薈ache 與內(nèi)存的一致性赡模。但是在多核 CPU 中田炭,由于每個(gè)核心都有一份獨(dú)占的 Cache,就會(huì)存在一個(gè)核心修改數(shù)據(jù)后漓柑,兩個(gè)核心 Cache 不一致的問題教硫。

舉個(gè)例子:

  • 1、Core 1 和 Core 2 讀取了同一個(gè)內(nèi)存塊的數(shù)據(jù)辆布,在兩個(gè) Core 都緩存了一份內(nèi)存塊的副本瞬矩。此時(shí),Cache 和內(nèi)存塊是一致的锋玲;

  • 2景用、Core 1 執(zhí)行內(nèi)存寫入操作:

    • 2.1 在寫直達(dá)策略中,新數(shù)據(jù)會(huì)直接寫回內(nèi)存惭蹂,此時(shí)伞插,Cache 和內(nèi)存塊一致。但由于之前 Core 2 已經(jīng)讀過這塊數(shù)據(jù)盾碗,所以 Core 2 緩存的數(shù)據(jù)還是舊的媚污。此時(shí),Core 1 和 Core 2 不一致置尔;

    • 2.2 在寫回策略中杠步,新數(shù)據(jù)會(huì)延遲寫回內(nèi)存,此時(shí) Cache 和內(nèi)存塊不一致榜轿。不管 Core 2 之前有沒有讀過這塊數(shù)據(jù)幽歼,Core 2 的數(shù)據(jù)都是舊的鹦牛。此時(shí)返顺,Core 1 和 Core 2 不一致怜俐。

  • 3茶敏、由于 Core 2 無法感知到 Core 1 的寫入操作葱峡,如果繼續(xù)使用過時(shí)的數(shù)據(jù)织鲸,就會(huì)出現(xiàn)邏輯問題默垄。

多核 Cache 不一致

可以看到:由于兩個(gè)核心的工作是獨(dú)立的型檀,在一個(gè)核心上的修改行為不會(huì)被其它核心感知到砸烦,所以不管 CPU 使用寫直達(dá)策略還是寫回策略弃鸦,都會(huì)出現(xiàn)緩存不一致問題。 所以幢痘,我們需要一種機(jī)制唬格,將多個(gè)核心的工作聯(lián)合起來,共同保證多個(gè)核心下的 Cache 一致性,這就是緩存一致性機(jī)制购岗。

4.1 寫傳播 & 事務(wù)串行化

緩存一致性機(jī)制需要解決的問題就是 2 點(diǎn):

  • 特性 1 - 寫傳播(Write Propagation): 每個(gè) CPU 核心的寫入操作汰聋,需要傳播到其他 CPU 核心;

  • 特性 2 - 事務(wù)串行化(Transaction Serialization): 各個(gè) CPU 核心所有寫入操作的順序喊积,在所有 CPU 核心看起來是一致烹困。

第 1 個(gè)特性解決了 “感知” 問題,如果一個(gè)核心修改了數(shù)據(jù)乾吻,就需要同步給其它核心髓梅,很好理解。但只做到同步還不夠绎签,如果各個(gè)核心收到的同步信號(hào)順序不一致女淑,那最終的同步結(jié)果也會(huì)不一致。

舉個(gè)例子:假如 CPU 有 4 個(gè)核心辜御,Core 1 將共享數(shù)據(jù)修改為 1000鸭你,隨后 Core 2 將共享數(shù)據(jù)修改為 2000。在寫傳播下擒权,“修改為 1000” 和 “修改為 2000” 兩個(gè)事務(wù)會(huì)同步到 Core 3 和 Core 4袱巨。但是,如果沒有事務(wù)串行化碳抄,不同核心收到的事務(wù)順序可能是不同的愉老,最終數(shù)據(jù)還是不一致。

非事務(wù)串行化

4.2 總線嗅探 & 總線仲裁

寫傳播和事務(wù)串行化在 CPU 中是如何實(shí)現(xiàn)的呢剖效?—— 此處隆重請(qǐng)出計(jì)算機(jī)總線系統(tǒng)嫉入。

  • 寫傳播 - 總線嗅探: 總線除了能在一個(gè)主模塊和一個(gè)從模塊之間傳輸數(shù)據(jù),還支持一個(gè)主模塊對(duì)多個(gè)從模塊寫入數(shù)據(jù)璧尸,這種操作就是廣播咒林。要實(shí)現(xiàn)寫傳播,其實(shí)就是將所有的讀寫操作廣播到所有 CPU 核心爷光,而其它 CPU 核心時(shí)刻監(jiān)聽總線上的廣播垫竞,再修改本地的數(shù)據(jù);

  • 事務(wù)串行化 - 總線仲裁: 總線的獨(dú)占性要求同一時(shí)刻最多只有一個(gè)主模塊占用總線蛀序,天然地會(huì)將所有核心對(duì)內(nèi)存的讀寫操作串行化欢瞪。如果多個(gè)核心同時(shí)發(fā)起總線事務(wù),此時(shí)總線仲裁單元會(huì)對(duì)競(jìng)爭(zhēng)做出仲裁徐裸,未獲勝的事務(wù)只能等待獲勝的事務(wù)處理完成后才能執(zhí)行遣鼓。

提示: 寫傳播還有 “基于目錄(Directory-base)” 的實(shí)現(xiàn)方案。

基于總線嗅探和總線仲裁重贺,現(xiàn)代 CPU 逐漸形成了各種緩存一致性協(xié)議骑祟,例如 MESI 協(xié)議宫补。

4.3 MESI 協(xié)議

MESI 協(xié)議其實(shí)是 CPU Cache 的有限狀態(tài)機(jī),一共有 4 個(gè)狀態(tài)(MESI 就是狀態(tài)的首字母):

  • M(Modified曾我,已修改): 表明 Cache 塊被修改過,但未同步回內(nèi)存健民;
  • E(Exclusive抒巢,獨(dú)占): 表明 Cache 塊被當(dāng)前核心獨(dú)占,而其它核心的同一個(gè) Cache 塊會(huì)失效秉犹;
  • S(Shared蛉谜,共享): 表明 Cache 塊被多個(gè)核心持有且都是有效的;
  • I(Invalidated崇堵,已失效): 表明 Cache 塊的數(shù)據(jù)是過時(shí)的型诚。

在 “獨(dú)占” 和 “共享” 狀態(tài)下,Cache 塊的數(shù)據(jù)是 “清” 的鸳劳,任何讀取操作可以直接使用 Cache 數(shù)據(jù)涵紊;

在 “已失效” 和 “已修改” 狀態(tài)下摸柄,Cache 塊的數(shù)據(jù)是 “臟” 的,它們和內(nèi)存的數(shù)據(jù)都可能不一致既忆。在讀取或?qū)懭?“已失效” 數(shù)據(jù)時(shí)驱负,需要先將其它核心 “已修改” 的數(shù)據(jù)寫回內(nèi)存,再從內(nèi)存讀然脊汀跃脊;

在 “共享” 和 “已失效” 狀態(tài)匾乓,核心沒有獲得 Cache 塊的獨(dú)占權(quán)(鎖)。在修改數(shù)據(jù)時(shí)不能直接修改又谋,而是要先向所有核心廣播 RFO(Request For Ownership)請(qǐng)求 拼缝,將其它核心的 Cache 置為 “已失效”,等到獲得回應(yīng) ACK 后才算獲得 Cache 塊的獨(dú)占權(quán)任斋。這個(gè)獨(dú)占權(quán)這有點(diǎn)類似于開發(fā)語言層面的鎖概念继阻,在修改資源之前,需要先獲取資源的鎖;

在 “已修改” 和 “獨(dú)占” 狀態(tài)下瘟檩,核心已經(jīng)獲得了 Cache 塊的獨(dú)占權(quán)(鎖)抹缕。在修改數(shù)據(jù)時(shí)不需要向總線發(fā)送廣播,能夠減輕總線的通信壓力墨辛。

事實(shí)上卓研,完整的 MESI 協(xié)議更復(fù)雜,但我們沒必要記得這么細(xì)睹簇。我們只需要記住最關(guān)鍵的 2 點(diǎn):

  • 關(guān)鍵 1 - 阻止同時(shí)有多個(gè)核心修改的共享數(shù)據(jù): 當(dāng)一個(gè) CPU 核心要求修改數(shù)據(jù)時(shí)奏赘,會(huì)先廣播 RFO 請(qǐng)求獲得 Cache 塊的所有權(quán),并將其它 CPU 核心中對(duì)應(yīng)的 Cache 塊置為已失效狀態(tài)太惠;

  • 關(guān)鍵 2 - 延遲回寫: 只有在需要的時(shí)候才將數(shù)據(jù)寫回內(nèi)存磨淌,當(dāng)一個(gè) CPU 核心要求訪問已失效狀態(tài)的 Cache 塊時(shí),會(huì)先要求其它核心先將數(shù)據(jù)寫回內(nèi)存凿渊,再從內(nèi)存讀取梁只。

提示: MESI 協(xié)議在 MSI 的基礎(chǔ)上增加了 E(獨(dú)占)狀態(tài),以減少只有一份緩存的寫操作造成的總線通信埃脏。

MESI 協(xié)議有一個(gè)非常 nice 的在線體驗(yàn)網(wǎng)站敛纲,你可以對(duì)照文章內(nèi)容,在網(wǎng)站上操作指令區(qū)剂癌,并觀察內(nèi)存和緩存的數(shù)據(jù)和狀態(tài)變化淤翔。網(wǎng)站地址:https://www.scss.tcd.ie/Jeremy.Jones/VivioJS/caches/MESI.htm

MESI 協(xié)議在線模擬

4.4 寫緩沖區(qū) & 失效隊(duì)列

MESI 協(xié)議保證了 Cache 的一致性,但完全地遵循協(xié)議會(huì)影響性能佩谷。 因此旁壮,現(xiàn)代的 CPU 會(huì)在增加寫緩沖區(qū)和失效隊(duì)列將 MESI 協(xié)議的請(qǐng)求異步化,以提高并行度:

  • 寫緩沖區(qū)(Store Buffer)

由于在寫入操作之前谐檀,CPU 核心 1 需要先廣播 RFO 請(qǐng)求獲得獨(dú)占權(quán)抡谐,在其它核心回應(yīng) ACK 之前,當(dāng)前核心只能空等待桐猬,這對(duì) CPU 資源是一種浪費(fèi)麦撵。因此,現(xiàn)代 CPU 會(huì)采用 “寫緩沖區(qū)” 機(jī)制:寫入指令放到寫緩沖區(qū)后并發(fā)送 RFO 請(qǐng)求后溃肪,CPU 就可以去執(zhí)行其它任務(wù)免胃,等收到 ACK 后再將寫入操作寫到 Cache 上。

  • 失效隊(duì)列(Invalidation Queue)

由于其他核心在收到 RFO 請(qǐng)求時(shí)惫撰,需要及時(shí)回應(yīng) ACK羔沙。但如果核心很忙不能及時(shí)回復(fù),就會(huì)造成發(fā)送 RFO 請(qǐng)求的核心在等待 ACK厨钻。因此扼雏,現(xiàn)代 CPU 會(huì)采用 “失效隊(duì)列” 機(jī)制:先把其它核心發(fā)過來的 RFO 請(qǐng)求放到失效隊(duì)列坚嗜,然后直接返回 ACK,等當(dāng)前核心處理完任務(wù)后再去處理失效隊(duì)列中的失效請(qǐng)求诗充。

寫緩沖區(qū) & 失效隊(duì)列

事實(shí)上苍蔬,寫緩沖區(qū)和失效隊(duì)列破壞了 Cache 的一致性。 舉個(gè)例子:初始狀態(tài)變量 a 和變量 b 都是 0蝴蜓,現(xiàn)在 Core1 和 Core2 分別執(zhí)行這兩段指令碟绑,最終 x 和 y 的結(jié)果是什么?

Core1 指令

a = 1; // A1
x = b; // A2

Core2 指令

b = 2; // B1
y = a; // B2

我們知道在未同步的情況下励翼,這段程序可能會(huì)有多種執(zhí)行順序。不管怎么執(zhí)行辜荠,只要 2 號(hào)指令是在 1 號(hào)指令后執(zhí)行的汽抚,至少 x 或 y 至少一個(gè)有值。但是在寫緩沖區(qū)和失效隊(duì)列的影響下伯病,程序還有以意料之外的方式執(zhí)行:

執(zhí)行順序(先不考慮 CPU 超前流水線控制) 結(jié)果
A1 → A2 → B1 → B2 x = 0, y = 1
A1 → B1 → A1 → B2 x = 2, y = 1
B1 → B2 → A1 → A2 x = 1, y = 0
B1 → A1 → B2 → A2 x = 2, y = 1
A2 → B1 → B2 → A1(A1 與 A2 重排) x = 0, y = 0
Core2 也會(huì)出現(xiàn)相同的情況造烁,不再贅述 x = 0, y = 0

上圖。

寫緩沖區(qū)造成指令重排

可以看到:從內(nèi)存的視角看午笛,直到 Core1 執(zhí)行 A3 來刷新寫緩沖區(qū)惭蟋,寫操作 A1 才算真正執(zhí)行了。雖然 Core 的執(zhí)行順序是 A1 → A2 → B1 → B2药磺,但內(nèi)存看到的順序卻是 A2 → B1 → B2 → A1告组,變量 a 寫入沒有同步給對(duì)變量 a 的讀取,Cache 的一致性被破壞了癌佩。


5. 總結(jié)

  • 1木缝、在 CPU Cache 的三級(jí)緩存中,會(huì)存在 2 個(gè)緩存一致性問題:

    • 縱向 - Cache 與內(nèi)存的一致性問題: 在修改 Cache 數(shù)據(jù)后围辙,如何同步回內(nèi)存我碟?
    • 橫向 - 多核心 Cache 的一致性問題: 在一個(gè)核心修改 Cache 數(shù)據(jù)后,如何同步給其他核心 Cache姚建?
  • 2矫俺、Cache 與內(nèi)存的一致性問題有 2 個(gè)策略:

    • 寫直達(dá)策略: 始終保持 Cache 數(shù)據(jù)和內(nèi)存數(shù)據(jù)一致,在每次寫入操作中都會(huì)寫入內(nèi)存掸冤;
    • 寫回策略: 只有在臟 Cache 塊被替換出去的時(shí)候?qū)懟貎?nèi)存厘托,減少寫回內(nèi)存的次數(shù);
  • 3稿湿、多核心 Cache 一致性問題需要滿足 2 點(diǎn)特性:

    • 寫傳播(總線嗅探): 每個(gè) CPU 核心的寫入操作催烘,需要傳播到其他 CPU 核心;
    • 事務(wù)串行化(總線仲裁): 各個(gè) CPU 核心所有寫入操作的順序缎罢,在所有 CPU 核心看起來是一致伊群。
  • 4考杉、MESI 協(xié)議能夠滿足以上 2 點(diǎn)特性,通過 “已修改舰始、獨(dú)占崇棠、共享、已失效” 4 個(gè)狀態(tài)實(shí)現(xiàn)了 CPU Cache 的一致性丸卷;

  • 5枕稀、現(xiàn)代 CPU 為了提高并行度,會(huì)在增加 寫緩沖區(qū) & 失效隊(duì)列 將 MESI 協(xié)議的請(qǐng)求異步化谜嫉, 從內(nèi)存的視角看就是指令重排萎坷,破壞了 CPU Cache 的一致性。

今天沐兰,我們主要討論了 CPU 的緩存一致性問題與對(duì)應(yīng)的緩存一致性協(xié)議哆档。這里有一個(gè)問題:既然 CPU 已經(jīng)實(shí)現(xiàn)了 MESI 協(xié)議,已經(jīng)在硬件層面實(shí)現(xiàn)了寫傳播和事務(wù)串行化住闯,為什么 Java 語言層面還需要定義 volatile 關(guān)鍵字呢瓜浸?豈不是多此一舉?

你可能會(huì)說因?yàn)閷懢彌_區(qū)和失效隊(duì)列破壞了 Cache 一致性比原。好插佛,那不考慮這個(gè)因素的話,還需要定義 volatile 關(guān)鍵字嗎量窘?這個(gè)問題我們?cè)?下一篇文章 展開討論雇寇,請(qǐng)關(guān)注。


參考資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末造壮,一起剝皮案震驚了整個(gè)濱河市渡讼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌耳璧,老刑警劉巖成箫,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異旨枯,居然都是意外死亡蹬昌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門攀隔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來皂贩,“玉大人栖榨,你說我怎么就攤上這事∶魉ⅲ” “怎么了婴栽?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長辈末。 經(jīng)常有香客問我愚争,道長,這世上最難降的妖魔是什么挤聘? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任轰枝,我火速辦了婚禮,結(jié)果婚禮上组去,老公的妹妹穿的比我還像新娘鞍陨。我一直安慰自己,他們只是感情好添怔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布湾戳。 她就那樣靜靜地躺著贤旷,像睡著了一般广料。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上幼驶,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天艾杏,我揣著相機(jī)與錄音,去河邊找鬼盅藻。 笑死购桑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的氏淑。 我是一名探鬼主播勃蜘,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼假残!你這毒婦竟也來了缭贡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤辉懒,失蹤者是張志新(化名)和其女友劉穎阳惹,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體眶俩,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡莹汤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了颠印。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纲岭。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抹竹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出荒勇,到底是詐尸還是另有隱情柒莉,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布沽翔,位于F島的核電站兢孝,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏仅偎。R本人自食惡果不足惜跨蟹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望橘沥。 院中可真熱鬧窗轩,春花似錦、人聲如沸座咆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽介陶。三九已至堤舒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間哺呜,已是汗流浹背舌缤。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留某残,地道東北人国撵。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像玻墅,于是被迫代替她去往敵國和親介牙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容