CPU Cache

CPU Cache結構

CPU包含多個核心,每個核心又有獨自的一級緩存(細分成代碼緩存和數據緩存)和二級緩存,各個核心之間共享三級緩存,并統一通過總線與內存進行交互

運行程序時,每個核心都有數據的一個副本(在各自的緩存中),這將會導致數據的一致性問題

Cache Line

整個Cache被分成多個Line,每個Line通常是32byte或64byte
Cache Line是Cache和內存交換數據的最小單位

每個Cache Line包含三個部分
Valid:當前緩存是否有效
Tag:對應的內存地址
Block:緩存數據

映射

主存與Cache的對應關系
將主存和Cache劃分成若干大小相等的塊

全關聯映射

主存任意一塊可以映射到Cache的任意一塊
優點:空間利用率高、命中率高
缺點:訪問存儲器時,每次都要全部查找,速度低,基本不使用

直接映射

主存中的一塊只能映射到Cache的一個特定的塊中
優點:映射簡單,訪問速度快
缺點:替換頻繁,命中率低

組相連映射

主存根據Cache大小劃分多個區,每個區劃分成多個組,每個組內劃分多個塊
Cache劃分成多個組,每個組內劃分多個塊
主存的每個區與Cache直接映射,組內采用全映射方式

替換策略

隨機

隨機確定要替換的塊

先進先出

選擇最先調入的塊進行替換

LRU(最近最少使用)

根據塊的使用情況,選擇最近最少使用的塊進行替換,反映了程序的局部性規律

寫模式

直寫(Write Through)

透過本級緩存,直接把數據寫到下一級緩存(或直接到內存)中,如果對應的段被緩存了,同時更新緩存中的內容(甚至直接丟棄)
緩存中的段永遠和它對應的內存內容匹配

寫回(Write Back)

緩存不會立即把寫操作傳遞到下一級,而是僅修改本級緩存中的數據,并且把對應的緩存段標記為“臟”段。臟段會觸發回寫,也就是把里面的內容寫到對應的內存或下一級緩存中。回寫后,臟段又變“干凈”了。當一個臟段被丟棄的時候,總是先要進行一次回寫
回寫定律:當所有的臟段被回寫后,任意級別緩存中的緩存段的內容,等同于它對應的內存中的內容
弱一致性:要么緩存段的內容和內存一致(如果緩存段是干凈的話),要么緩存段中的內容最終要回寫到內存中(對于臟緩存段來說)
優點:能過濾掉對同一地址的反復寫操作,并且,如果大多數緩存段都在回寫模式下工作,那么系統經常可以一下子寫一大片內存,而不是分成小塊來寫,前者的效率更高

一致性

單核是沒有問題的,但多核情況下,每個核都有自己的緩存,該如何確保各核緩存數據的一致性?

窺探協議

所有內存傳輸都發生在一條共享的總線上,而所有的處理器都能看到這條總線:緩存本身是獨立的,但是內存是共享資源,所有的內存訪問都要經過仲裁(arbitrate):同一個指令周期中,只有一個緩存可以讀寫內存。
緩存不僅僅在做內存傳輸的時候才和總線打交道,而是不停地在窺探總線上發生的數據交換,跟蹤其他緩存在做什么。所以當一個緩存代表它所屬的處理器去讀寫內存時,其他處理器都會得到通知,它們以此來使自己的緩存保持同步。只要某個處理器一寫內存,其他處理器馬上就知道這塊內存在它們自己的緩存中對應的段已經失效。
在直寫模式下,是很直接的,因為寫操作一旦發生,它的效果馬上會被“公布”出去,確保所有核都得到通知
在回寫模式下,就有問題了,因為有可能在寫指令執行過后很久,數據才會被真正回寫到物理內存中。在這段時間內,其他處理器的緩存也可能會去寫同一塊內存地址,導致沖突

MESI緩存一直性協議

每個Cache line有2個標志:dirty(數據是否被修改)和valid(數據是否有效)標志,描述了Cache和主存之間的數據關系

在MESI協議中,每個Cache line有4個狀態

狀態 描述
M(Modified) 數據有效,數據被修改了,和內存中的數據不一致,數據只存在于本Cache中
E(Exclusive) 數據有效,數據和內存中的數據一致,數據只存在于本Cache中
S(Shared) 數據有效,數據和內存中的數據一致,數據存在于很多Cache中
I(Invalid) 這行數據無效

M(Modified)和E(Exclusive)狀態的Cache line,數據是獨有的,不同點在于M狀態的數據是dirty的(和內存的不一致),E狀態的數據是clean的(和內存的一致)
S(Shared)狀態的Cache line,數據和其他Core的Cache共享。只有clean的數據才能被多個Cache共享

E狀態
只有Core 0訪問變量x,它的Cache line狀態為E(Exclusive)

S狀態
3個Core都訪問變量x,它們對應的Cache line為S(Shared)狀態

M狀態和I狀態
Core 0修改了x的值之后,這個Cache line變成了M(Modified)狀態,其他Core對應的Cache line變成了I(Invalid)狀態

MESI協議狀態遷移
Local Read表示本內核讀本Cache中的值,Local Write表示本內核寫本Cache中的值,Remote Read表示其它內核讀其它Cache中的值,Remote Write表示其它內核寫其它Cache中的值,箭頭表示本Cache line狀態的遷移,環形箭頭表示狀態不變

當前狀態 事件 行為 下一個狀態
I(Invalid) Local Read 如果其它Cache沒有這份數據,本Cache從內存中取數據,Cache line狀態變成E;如果其它Cache有這份數據,且狀態為M,則將數據更新到內存,本Cache再從內存中取數據,2個Cache 的Cache line狀態都變成S;如果其它Cache有這份數據,且狀態為S或者E,本Cache從內存中取數據,這些Cache 的Cache line狀態都變成S E/S
Local Write 從內存中取數據,在Cache中修改,狀態變成M;如果其它Cache有這份數據,且狀態為M,則要先將數據更新到內存;如果其它Cache有這份數據,則其它Cache的Cache line狀態變成I M
Remote Read 既然是Invalid,別的核的操作與它無關 I
Remote Write 既然是Invalid,別的核的操作與它無關 I
E(Exclusive) Local Read 從Cache中取數據,狀態不變 E
Local Write 修改Cache中的數據,狀態變成M M
Remote Read 數據和其它核共用,狀態變成了S S
Remote Write 數據被修改,本Cache line不能再使用,狀態變成I I
S(Shared) Local Read 從Cache中取數據,狀態不變 S
Local Write 修改Cache中的數據,狀態變成M,其它核共享的Cache line狀態變成I M
Remote Read 狀態不變 S
Remote Write 數據被修改,本Cache line不能再使用,狀態變成I I
M(Modified) Local Read 從Cache中取數據,狀態不變 M
Local Write 修改Cache中的數據,狀態不變 M
Remote Read 這行數據被寫到內存中,使其它核能使用到最新的數據,狀態變成S S
Remote Write 這行數據被寫到內存中,使其它核能使用到最新的數據,由于其它核會修改這行數據,狀態變成I I

*MESI定律:在所有的臟緩存段(M狀態)被回寫后,任意緩存級別的所有緩存段中的內容,和它們對應的內存中的內容一致。此外,在任意時刻,當某個位置的內存被一個處理器加載入獨占緩存段時(E狀態),那它就不會再出現在其他任何處理器的緩存中。

偽共享(false sharing)

發生在不同處理器上的線程修改位于同一個cache line的變量的情景下(本來每個線程都訪問不同的數據,不會造成同步問題,但因為數據都處于同一cache line中,根據MESI協議,cache line中任意數據的修改都需要同步給其他內核,導致不應同步的操作變成同步了)
這會導致cache line失效并強制刷新,因此導致性能下降

解決辦法:字節對齊,將字節填滿一個cache line
Java中主要有sun.misc.Contended和Disruptor框架

參考

每個程序員都應該了解的CPU高速緩存
關于CPU Cache -- 程序猿需要知道的那些事
緩存一致性(Cache Coherency)入門
《大話處理器》Cache一致性協議之MESI
偽共享(False Sharing)
Java 7與偽共享的新仇舊恨
Java8中用sun.misc.Contended避免偽共享(false sharing)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,001評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,786評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,986評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,204評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,964評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,354評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,410評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,554評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,106評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,918評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,093評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,648評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,342評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,755評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,009評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,839評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,107評論 2 375

推薦閱讀更多精彩內容