某个地点std::memory_order_release
的商店可以通过std::memory_order_acquire
的其他地点的后续加载进行重新排序。
但是std::memory_order_release
到某个位置的商店是否可以通过std::memory_order_seq_cst
的其他位置的后续加载进行重新排序?
类似地,对std::memory_order_seq_cst
变量std::memory_order_acquire
的商店是否可以使用std::atomic<int> x{0};
std::atomic<int> y{0};
void thread1() {
x.store(std::memory_order_release, 1);
int r1 = y.load(std::memory_order_seq_cst);
std::cout << r1 << std::endl;
}
void thread2() {
y.store(std::memory_order_seq_cst, 1);
int r2 = x.load(std::memory_order_acquire);
std::cout << r2 << std::endl;
}
来自其他位置的后续加载进行重新排序?
考虑这个例子:
std::memory_order_seq_cst
众所周知(http://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/)如果{{1}}被他们的释放/获得对象替换,则输出可能是“0”的两倍。
顺序一致性在本例中是否购买任何东西,或者输出仍然是“0”的两倍?
答案 0 :(得分:2)
不,顺序一致性在这个例子中没有买任何东西,输出仍然是两次&#34; 0&#34;。
std::memory_order_seq_cst
和std::memory_order_acquire/release
之间的唯一区别是std::memory_order_seq_cst
- 商店可能无法与后续std::memory_order_seq_cst
重新排序 - 加载到不同的变量/ locations,参见Herb Sutter&#34; atomic&lt;&gt;武器&#34;谈论。 (当然,可能永远不会发生商店重新排序,后续加载到同一个变量。)
但是,只要一个(更不用说两者)内存命令被削弱(如示例中的两个线程中的情况),就可能发生StoreLoad重新排序。这意味着,在示例中,两个负载可以在它们各自的存储之前重新排序。
这意味着只有一个std::memory_order_seq_cst
,而且只有std::memory_order_release/acquire
的程序仍然是同一个程序,如果要用std::memory_order_seq_cst
替换孤独的std::memory_order_release
(如果它是一个商店)或std::memory_order_acquire
(如果有负载)。