記憶體一致性模型

2022-03-26 06:12:08 字數 2689 閱讀 7955

cache coherence

本文主要討論的是記憶體一致性問題(memory consistency),和快取一致性(cache coherence)是不同的。在《計算機體系結構:量化方法研究》第五章中,memory consistency是由cache coherence引出的,所以我們就先來說說cache coherence吧。考慮下圖:

如圖,a和b讀取x到快取後,a直寫(write through)x的值為0,但此時b快取中儲存的x的值仍然是1。即如果此時b讀取x,將會收到數值1!

通俗地說,如果在每次讀取某一資料項時都會返回該資料項的最新寫入值,則稱這個儲存系統是一致的。這一定義有些含糊和簡單,卻包含了兩個關鍵的方面:

1.coherence確定了讀取操作可能返回什麼值;

2.consistency確定了寫入值什麼時候讀取操作返回。

簡單來說,coherence其實保證的就是對某乙個位址的讀操作返回的值一定是那個位址的最新值(注意coherence和consistency最大的區別就是是對某乙個位址還是全域性),而這個最新值可能是該執行緒所處的cpu核心剛剛寫進去的那個最新值,也可能是另乙個cpu核心上的執行緒剛剛寫進去的最新值。具體嚴謹的定義我直接從書上截圖好了:

這三個條件只是保證了coherence,還未考慮consistency的問題。比如,如果乙個處理器對x的寫入操作僅比另乙個處理器對x的讀取操作提前很短的一點時間,那就不可能確保該讀取操作會返回這個寫入值。這個寫入值多久後能確保被讀取操作讀取到,這正是memory consistency討論的問題。

memory consistency model

這部分我主要參考的是《shared memory consistency models:a tutorial》這篇文章。先說一下最簡單的順序一致性(sequential consistency)。定義如下:

這個定義包含兩個方面:1.在每個處理器內,維護程式次序;

2.在所有處理器間維護乙個單一的操作次序,即所有處理器看到的操作次序要一樣。這就使記憶體操作需要有原子性(或瞬發性)。

圖 a 闡述了 sc 對程式次序的要求(要求一)。當處理器 p1 想要進入臨界區時,

它先將 flag1 更新為 1, 再去判斷 p2 是否嘗試進入臨界區(flag2). 若 flag2 為 0,

表示 p2 未嘗試進入臨界區,此時 p1 可以安全進入臨界區。這個演算法假設如果 p1 中讀到 flag2 等於0, 那麼p1的寫操作(flag1=1)會在p2

的寫操作和讀操作之前發生,這可以避免 p2 也進入臨界區。sc 通過維護程式次序來保證這一點。

圖 b 闡述了原子性要求。原子性允許我們假設 p1 對 a 的寫操作對整個系統(p2, p3) 是同時可見的:p1 將 a 寫成1; p2 先看到 p1 寫 a 後才寫 b;p3 看到 p2 寫 b 後才去讀 a, p3 此時讀出的 a 必須要是 1 (而不會是0)因為從 p2 看來操作執行次序為 (a=1)->(b=1), 不允許p3在看到操作 b=1 時,沒有看到 a=1.

實現sc需要付出代價,使效能降低,同時也會限制編譯器的優化。為了獲得更好的效能,引入寬鬆記憶體一致性模型(relaxed memory consistency models).

根據《量化》一書,relaxed memory consistency models有多種模型,比如放鬆w->r;放鬆w->w;放鬆 r->w 和 r->r,這包括多種模型,其中release consistency我們單獨拿出來說。

release consistency

release consistency包含兩個同步操作,acquire和release。

1)  acquire:  對於所有其它參與者來說, 在此操作後的所有讀寫操作必然發生在acquire這個動作之後。

2)  release:  對於所有其它參與者來說, 在此操作前的所有讀寫操作必然發生在release這個動作之前。

注意, 這其中任意乙個操作, 都只保證了一半的順序:

對於acquire來說, 並沒保證acquire前的讀寫操作不會發生在acquire動作之後.

對於release來說, 並沒保證release後的讀寫操作不會發生在release動作之前.

因此release和acquire的組合形成了記憶體屏障。舉個例子

處理器a執行以下**:

a.store(3

);b.store(4);

m.store(

5, release);

處理器b執行以下**:

m.load(acquire);

g.load();

h.load();

release和acquire組成的記憶體屏障保證了當執行緒 b 執行完m.load(acquire);之後, 執行緒 b 必須已經能看到a==3,b==4,且g和h的load操作不會發生在處理器a的release操作之前。

強一致性 弱一致性 最終一致性

這種方式在es等分布式系統中也有體現,可以設定主shard提交即返回成功,或者需要replica shard提交成功再返回。提到分布式架構就一定繞不開 一致性 問題,而 一致性 其實又包含了資料一致性和事務一致性兩種情況,本文主要討論資料一致性 事務一致性指acid 複製是導致出現資料一致性問題的唯...

dma記憶體一致性

核心的dma一般在平台初始化的時候已經分配好了。但是對於一些有內部dma的硬體ip,比如usb ip video加速ip,他們可能由ip廠商封裝好的,沒辦法繫結到cpu端,這時候在核心使用dma就要注意了,因為dma只認識實體地址哦。當然,辦法還是有的,look 以下來自 這兩天在做 dma 相關開...

記憶體管理 快取一致性

計算機在執行程式時,每條指令都是在cpu中執行的,而執行指令過程中,涉及到資料的讀取和寫入。由於程式執行過程中的臨時資料是存放在sram 物理記憶體 當中的,由於cpu執行速度很快,而從記憶體讀取數 據和向記憶體寫入資料的過程跟cpu執行指令的速度比起來要慢的多,因此如果任何時候對資料的操作都要通過...