今日的行程:
辦公室:10:00 - 11:30
讀書室:23:00 - 23:30
今日的記錄:
記錄公司禮拜五的讀書會內容
RISC-V 提供了 memory barrier 指令: fence {iorw}, {iorw},來解決這個問題。
以上述的問題,需要修改程式碼如下:
CPU 0 CPU 1
----------------------------------------------------
void func0 () void func1()
{ {
a = 1; while (b == 0) continue;
// fence w, w // fence r, r
smp_wmb(); smp_rmb();
b = 1; assert (a == 1);
} }
加入了 smp_wmb 後,會使得 store buffer 例的執行順序變為 (主要觀察 CPU 0 寫入 b = 1 的變化):
CPU 0 CPU 1
T0 ----------------------------------------------------------------------
寫 "a = 1" 到 store buffer
送寫訊號到 bus 上
T1 ----------------------------------------------------------------------
讀 b 的值
送 read 訊號到 bus 上 (看有沒有其他 CPU 有 b)
T2 ----------------------------------------------------------------------
執行 "smp_wmb"
(標記 store buffer 中的 entry)
T3 ----------------------------------------------------------------------
把 "b = 1" 寫入 store buffer 中
T4 ----------------------------------------------------------------------
收到 bus 來的 read 訊號
把 b 的值 (b == 0) 送到 bus 上
b 狀態變成 shared
T4 ----------------------------------------------------------------------
收到 b 的值,b == 0,b 變為 shared
繼續 loop
T5 ----------------------------------------------------------------------
收到寫訊號,inval. a,回一個 ACK
T6 ----------------------------------------------------------------------
store buffer entry 有標記過的 a = 1,
寫到 cache 中,a 改為 Modified 狀態
T7 ----------------------------------------------------------------------
store buffer entry 中的 b = 1,
寫到 cache 中,a 改為 Modified 狀態,
並送一個寫訊號到 bus 上
T8 ----------------------------------------------------------------------
讀取 b, b == 1 (省略中間的訊號傳遞過程)
T9 ----------------------------------------------------------------------
讀取 a, a == 1 (省略中間的訊號傳遞過程)
符合預期
T10 ----------------------------------------------------------------------
使得 invalidate queue 例的執行順序變為:
CPU 0 CPU 1
T0 ----------------------------------------------------------------------
寫 "a = 1" 到 store buffer
送寫訊號到 bus 上
T1 ----------------------------------------------------------------------
讀 b 的值
送 read 訊號到 bus 上 (看有沒有其他 CPU 有 b)
T2 ----------------------------------------------------------------------
收到寫訊號,把 inval. a 加入 invalidate queue
回覆 ACK
T3 ----------------------------------------------------------------------
把 "a = 1" 從 store buffer 寫入 cache
狀態變成 Modified,a == 1
T4 ----------------------------------------------------------------------
執行 "b = 1",狀態為 Modified
T5 ----------------------------------------------------------------------
收到讀訊號,把 b 的值送到 bus 上
T6 ----------------------------------------------------------------------
收到 b 的值,b == 1
跳出 while
T7 ----------------------------------------------------------------------
執行 smp_rmb,invalidate a
T8 ----------------------------------------------------------------------
讀取 a,a == 1 (省略訊號傳遞過程)
符合預期
T9 ----------------------------------------------------------------------