1

ある場所へのストアは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;
}

両方が対応する release/acquire に置き換えられた場合、出力std::memory_order_seq_cstが 2回「0」。

この例では、逐次一貫性によって何かが得られますか?それとも、出力が「0」の 2 倍のままになる可能性がありますか?

4

1 に答える 1

2

いいえ、この例では逐次一貫性は何の役にも立たず、出力は依然として「0」の 2 倍になる可能性があります。

との唯一の違いは、std::memory_order_seq_cst-storesは、異なる変数/場所への後続の -loadsで並べ替えられない可能性があることです。Herb Sutter の「atomic<> Weapons」の講演を参照してください。(もちろん、同じ変数への後続のロードでストアが並べ替えられることは決してないかもしれません。)std::memory_order_acquire/releasestd::memory_order_seq_cststd::memory_order_seq_cst

しかし、メモリ順序の 1 つだけ (両方は言うまでもなく) が弱くなるとすぐに (例の両方のスレッドの場合のように)、StoreLoad の並べ替えが発生する可能性があります。つまり、この例では、両方のロードがそれぞれのストアの前に並べ替えられる可能性があります。

これは、単一のプログラムのみを含み、それ以外の場合は、孤独を(ストアの場合) または(ロードの場合)に置き換えた場合にstd::memory_order_seq_cstのみ同じプログラムのままであることを意味します。std::memory_order_release/acquirestd::memory_order_seq_cststd::memory_order_releasestd::memory_order_acquire

于 2014-11-27T21:23:39.003 に答える