3 回答

TA貢獻1843條經驗 獲得超7個贊
問題中的更新的1代碼( 在線程4中進行了裝載x和y交換)實際上測試了所有線程是否同意全局存儲順序。
在C ++ 11內存模型下,結果r1==1, r2==0, r3==2, r4==0是允許的,實際上在POWER上是可觀察的。
在x86上,這種結果是不可能的,因為在那里“其他處理器以一致的順序看到存儲”。在順序一致執行中也不允許此結果。
注:1:這個問題原本有兩個讀者閱讀x,然后y。甲順序一致的執行是:
-- Initially --
std::atomic<int> x{0};
std::atomic<int> y{0};
-- Thread 4 --
int r3 = x.load(std::memory_order_acquire);
-- Thread 1 --
x.store(1, std::memory_order_release);
-- Thread 3 --
int r1 = x.load(std::memory_order_acquire);
int r2 = y.load(std::memory_order_acquire);
-- Thread 2 --
y.store(2, std::memory_order_release);
-- Thread 4 --
int r4 = y.load(std::memory_order_acquire);
結果是r1==1, r2==0, r3==0, r4==2。因此,這根本不是一個奇怪的結果。
為了說每個讀者看到的商店順序不同,我們需要他們以相反的順序閱讀,以排除最后一個商店只是被延遲了。

TA貢獻1817條經驗 獲得超6個贊
是怪異的結果 r1==1, r2==0,并r3==0, r4==2有可能在C ++ 11內存模型下,這種情況下?
是。C ++內存模型允許這種奇怪的結果。
如果我要全部替換std::memory_order_acq_rel成該std::memory_order_relaxed怎么辦?
如果更換所有memory_order_acquire和memory_order_release通過memory_order_relaxed,沒有什么改變你的代碼。
std::memory_order_seq_cst就像,std::memory_order_acq_rel但是std::memory_order_acquire-loads在std::memory_order_release-writes 之前可能不會移動。我看不到上面示例中的此附加約束如何防止出現奇怪的結果。
“ acquire-load可能不會在release-writes 之前移動?!?顯示了順序一致性約束(memory_order_seq_cst)的一方面。
在C ++內存模型中,它僅保證seq_cst具有acq_rel語義,并且所有 seq_cst原子訪問不會多多少少都具有“總順序”。當存在這樣的“總順序”時,我們無法得到怪異的結果,因為所有seq_cst原子訪問都好像在單個線程上以任何交錯順序執行一樣。
您先前的問題對待單個原子變量的“一致性” ,而這個問題要求所有原子變量的“一致性” 。C ++內存模型可確保單個原子變量甚至最弱的排序()的直觀一致性relaxed,以及不同原子變量的“順序一致性”,只要默認排序(seq_cst)。seq_cst如您所指出的那樣,當您使用顯式無序原子訪問時,這可能是奇怪的結果。
- 3 回答
- 0 關注
- 577 瀏覽
添加回答
舉報