在英特爾手冊第 3 卷中,有一個使用早期商店重新排序負載的示例。
最初x = y = 0
核心1:
mov [x], 1
mov r2, [y]
核心2:
mov [y], 1
mov r1, [x]
所以r1 = r2 = 0是可能的。問題是要求獲取釋放是否禁止這種情況?在 x86 商店是一個發布商店,所以我認為沒有。例子:
核心1:
release(mov [x], 1)
mov r2, [y]
核心2:
mov [y], 1
acquire(mov r1, [x])
在這種情況下,如果acquire(mov r1, [x])負載觀察到 0,則只能得出結論,就C11 標準記憶體模型規范release(mov [x], 1)的立場而言,它不同步 ,并且它不提供任何可以禁止重新排序和在Core 2上的保證acquire(mov r1, [x])mov [y], 1acquire(mov r1, [x])
uj5u.com熱心網友回復:
正確,獲取/釋放語意不能阻止 StoreLoad 重新排序,即先存盤,然后加載并交換它們的順序。對于 x86 上的普通加載和存盤指令,這種重新排序是允許的。
如果要避免在 C11 中進行此類重新排序,則需要memory_order_seq_cst同時在存盤和加載上使用。在 x86 匯編中,您需要在兩條指令之間設定屏障。 mfence用于此目的,但任何locked read-modify-write 指令xchg也是如此,包括即使沒有lock前綴也是如此。因此,如果您查看生成的操作程式集memory_order_seq_cst,您會在兩者之間看到一些這樣的障礙。(出于某些原因,類似lock add [rsp], 0, 或xchg在某些內容不重要的暫存器和記憶體之間,實際上可能比 性能更高mfence,因此即使看起來很奇怪,一些編譯器也會這樣做。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/504225.html
標籤:Intel Collective C 多线程 部件 x86 x86-64
