文章目錄
- atomicity of memory accesses
- ? 正確認識原子性的邊界
- 對于 **Load**:
- ? 正確的原子性邊界是:
- 對于 **Store**:
- ? 正確的原子性邊界是:
- 🔄 修正原文中的說法(對照分析)
- ? 原子性邊界最終澄清總結
- 為什么 Sequential Consistency的兩個核心約束 不提 read atomicity ?
- 🎯 問題本質
- ? 回答:因為 "Read Atomicity" 本身在 SC 中是隱含成立的,不需要單獨強調
- 🧠 思考路徑如下:
- 1. **Read 是不可觀察的副作用**
- 2. **讀的行為完全依賴于寫是否可見**
- 3. **讀操作在 SC 中沒有并發可見性問題**
- 📌 舉個例子說明
- ? 總結
- 從實現角度講,并不需要額外引入“read atomicity”機制,只要確保讀不會從“未完成的寫”中讀到值即可。
atomicity of memory accesses
原子性邊界的界定—是理解 memory model 的核心之一。
SC 要求 atomicity of memory accesses , 下面將 memory accesses 進行拆解, 以 更深刻理解 SC 對 atomicity 的要求。
? 正確認識原子性的邊界
對于 Load:
步驟回顧:
- 地址計算(EA)
- 發起訪問(向 cache 發 load 請求) ← Issue
- 從 cache/mem 返回值 ← Perform point
- 寫入目標寄存器
? 正確的原子性邊界是:
- 第 2 步(issue) 到 第 3 步(fetch 到值) 是 必須原子的部分。
- 原因:這是 load 真正與 memory hierarchy 交互的部分,如果其他 store 在這之間插入,會導致讀取到錯誤值,破壞 SC。
?注意:寫入寄存器不是 memory model 的可見性關鍵,因此不是原子性邊界的一部分。
對于 Store:
步驟回顧:
- 地址計算
- 指令 commit,進入 store buffer
- 從 store buffer 發起寫 cache(store buffer flush)
- 寫入緩存并完成 coherence 動作(例如 invalidate 或 update) ← Perform point
? 正確的原子性邊界是:
- 第 3 步(issue to cache) 到 第 4 步(完成全局可見性) 是 必須原子的部分。
- 原因:這決定了其他 core 能否讀到這個 store 的值,如果這個過程可被插入或拆分,就會打破 memory consistency。
?所以你說的 store 的 perform 階段是必須原子的 —— 是完全正確的。
🔄 修正原文中的說法(對照分析)
我之前說:
“Load 的兩個階段(issue, completion)構成其原子性邊界。”
→ ? 正確,但需要明確 “completion” 是指 從 cache 得到值,不是寫入寄存器。
我之前說:
“Store 的邊界是從 issue 到 perform(全局可見)。”
→ ? 正確,但更精確地講是:從 store buffer flush 到 coherence 完成 是關鍵部分。
? 原子性邊界最終澄清總結
操作類型 | 開始點 | 結束點 |
---|---|---|
Load | 發起 cache read | 數據拿到為止 |
Store | 發起 cache write | 數據在所有核心可見為止 |
為什么 Sequential Consistency的兩個核心約束 不提 read atomicity ?
你問得非常到位。這關系到 Sequential Consistency (SC) 模型中的核心假設和設計目標。
🎯 問題本質
你提到的兩個約束其實是:
- 程序順序對所有處理器都一致可見:每個處理器的指令(load/store)必須以程序寫的順序在系統中對所有處理器保持一致的順序。
- 寫操作必須具有原子性(write atomicity):一旦某個處理器看到一個寫(store)發生了,那么所有處理器必須同時看到這個寫。
于是問題來了:
為什么只強調了 Write Atomicity,而沒有強調 Read Atomicity?
? 回答:因為 “Read Atomicity” 本身在 SC 中是隱含成立的,不需要單獨強調
🧠 思考路徑如下:
1. Read 是不可觀察的副作用
讀(load)操作不會對其他核心產生直接可觀察的副作用,它只是讀取某個內存位置的當前值,并不會改變共享狀態。而寫操作會改變共享狀態,是全局可觀察事件。
所以,SC 中只需要定義:寫什么時候被"別人"看到;讀自然是基于"可見的寫"結果。
2. 讀的行為完全依賴于寫是否可見
在 SC 中,讀到的值必須是某個已經完成的寫,也就是說:
如果一個 core 看到
x = 1
,那么在它看來x = 1
這個寫已經 globally visible 了(write atomicity 確保的)。
讀到這個值是"合法"的前提是這個值是來自某個已經發生且"所有人都同意的"寫。這一點正是 write atomicity 保證的。
所以 SC 中不需要額外聲明 “read atomicity”——讀只是在一組可見寫中選一個。
3. 讀操作在 SC 中沒有并發可見性問題
- 寫的非原子性會導致 不同 core 看到不同寫入值,所以必須強調 atomicity。
- 但讀不會被“別人看到”,所以不會產生一致性問題。
因此,“read atomicity”沒有意義:它不是一個互斥事件,也不需要所有 core "看到"某個讀行為——它只是個本地動作。
📌 舉個例子說明
// P0
x = 1;
y = 1;// P1
if (y == 1)assert(x == 1);
SC 要求:
- P0 的 store 順序是 x=1 → y=1
- 如果 P1 看到 y1,那么由于 store 順序一致性,它也必須看到 x1(因為 x=1 寫在前)
關鍵是:
- 寫操作(x=1, y=1)必須在所有 core 看起來順序一致
- 讀操作(y1, x1)只是根據這些寫的“時間點”來決定自己的返回值,不存在“可見性”問題
? 總結
類型 | 是否強調原子性 | 原因 |
---|---|---|
Write | ? 強調 | 寫影響全局狀態,需要保證對所有核心同時可見 |
Read | ? 不強調 | 讀只是查詢當前狀態,不會影響其他核心,不存在多核心“看到”問題 |
所以:SC 模型中只需要定義 Write Atomicity,Read Atomicity 不是一個有意義的概念。
如果你在考慮更弱的 memory model(如 TSO, RCsc, ARM, RISC-V 等),那時讀操作就可能變得“更復雜”,因為 load-store reordering 和緩存的本地視圖都會造成讀操作行為更微妙。在那種模型下,load 有時也需要 fence 或 acquire-semantics 來保證語義,但那是更進一步的問題了。你也可以繼續問這方面的內容。