1

带有std::memory_order_releaseto 某个位置的商店可以重新排序,随后从另一个位置加载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;
}

众所周知(http://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/)如果两者std::memory_order_seq_cst都被它们的释放/获取对应物替换,输出可能是两个乘以“0”。

在这个例子中,顺序一致性是否可以购买任何东西,或者输出仍然可以是“0”的两倍?

4

1 回答 1

2

不,在这个例子中,顺序一致性没有买任何东西,输出仍然可以是“0”的两倍。

std::memory_order_seq_cst和之间的唯一区别std::memory_order_acquire/releasestd::memory_order_seq_cst-stores 可能不会随着后续的std::memory_order_seq_cst-loads 重新排序到不同的变量/位置,请参阅 Herb Sutter 的“atomic<> Weapons”演讲。(当然,可能永远不会发生存储在随后加载到同一个变量时重新排序的情况。)

但是,一旦只有一个(更不用说两个)内存顺序被削弱(如示例中的两个线程中的情况),可能会发生 StoreLoad 重新排序。这意味着,在示例中,两个加载都可以在它们各自的存储之前重新排序。

这意味着一个程序只包含一个单独的程序,std::memory_order_seq_cst否则只有std::memory_order_release/acquire在将寂寞替换为(如果它带有商店)或 a(如果它带有负载)时,它才会保持相同std::memory_order_seq_cststd::memory_order_release程序std::memory_order_acquire

于 2014-11-27T21:23:39.003 回答