可以使用C ++ 11中的后续顺序一致加载对存储释放进行重新排序吗?

时间:2014-11-27 21:23:39

标签: c++ c++11 memory-model stdatomic

某个地点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”的两倍?

1 个答案:

答案 0 :(得分:2)

不,顺序一致性在这个例子中没有买任何东西,输出仍然是两次&#34; 0&#34;。

std::memory_order_seq_cststd::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(如果有负载)。