多核心、一致性與執行緒層級平行

快取一致性(cache coherence)

想像好幾位編輯各自拿著同一頁的影印本工作。那頁存在圖書館(主記憶體)裡,但為了快,每位編輯在自己桌上留一份私人影印本(他們的快取)。現在一位編輯在自己那份上劃掉了一句話。其他人還在各自的影印本上讀著舊句子,圖書館的母本也過時了。誰的副本才是真的?快取一致性(cache coherence)就是那條規則和那套機制,確保所有副本達成一致,讓任何核心都不會讀到另一個核心已經覆寫過的值。

問題說精確一點。在多核心晶片裡,每個核心有私有快取,共享資料可能同時躺在好幾個快取裡。若核心 A 把一個新值寫進它對位址 X 的快取副本,核心 B 對 X 的快取副本現在就過時了——但 B 會樂呵呵地把它讀出,並對錯誤的資料運算。一致的系統保證兩件事:對 X 的讀取會回傳對 X 最近一次的寫入(寫入傳播),而且所有核心對 X 的寫入順序達成一致(寫入序列化)。它的做法是讓快取追蹤每一條快取列的狀態,並在另一個核心碰到同一條列時做出反應。

一致性是自動的、對正確性而言是隱形的——軟體不必要求,硬體就提供——這很美好,但並非免費。讓副本保持一致,意味著只要共享資料被寫入,核心就得在幕後溝通:使其他副本失效或更新它們,這要花週期和頻寬。兩大協定家族做這份工作:監聽(snooping)與目錄(directory);還有一個叫偽共享(false sharing)的微妙效能陷阱,會在核心其實碰的是邏輯上各自獨立的資料時,仍讓一致性流量爆增。一致性是共享記憶體那筆無聲的稅。

核心 A 和核心 B 都快取了 X = 5。核心 A 寫入 X = 6。沒有一致性,B 仍從自己的快取讀到 X = 5 而算錯。有了一致性,A 的寫入要嘛使 B 的副本失效(於是 B 下次讀取未命中、提取到 6),要嘛更新它(於是 B 的副本立刻變成 6)。無論哪種方式,B 都絕不可能讀到過時的 5。

一致性保證讀取會回傳最近的寫入——靠著在共享資料改變時,使其他核心過時的副本失效或更新它。

一致性(單一位址的所有副本是否對其最新值達成一致?)不同於記憶體一致性模型(對不同位址的寫入可以用什麼順序變得可見?)。一個系統可以是連貫的,卻仍允許令人驚訝的順序。

又称
coherence快取連貫性