アトミック操作の C++11 メモリ順序付けパラメーターは、順序付けに関する制約を指定します。でストアを実行し、std::memory_order_release別のスレッドからのロードが で値を読み取る場合std::memory_order_acquire、2 番目のスレッドからの後続の読み取り操作では、最初のスレッドによって任意のメモリ位置に格納された、ストア リリースの前、またはそれ以降の値が表示されます。これらのメモリ ロケーションのいずれかに保存します。
ストアと後続のロードの両方が である場合、std::memory_order_seq_cstこれら 2 つのスレッド間の関係は同じです。違いを確認するには、より多くのスレッドが必要です。
たとえば、std::atomic<int>変数xとy、どちらも最初は 0 です。
スレッド 1:
x.store(1,std::memory_order_release);
スレッド 2:
y.store(1,std::memory_order_release);
スレッド 3:
int a=x.load(std::memory_order_acquire); // x before y
int b=y.load(std::memory_order_acquire);
スレッド 4:
int c=y.load(std::memory_order_acquire); // y before x
int d=x.load(std::memory_order_acquire);
x書かれているように、とのストアの間に関係はありません。そのため、スレッド 3 とスレッド 4 で 、およびがy表示される可能性は十分にあります。a==1b==0c==1d==0
すべてのメモリ順序が に変更された場合、ストアとstd::memory_order_seq_cstの間の順序が強制されます。したがって、スレッド 3 がandを参照した場合、それはストア to がストア to の前にある必要があることを意味し、スレッド 4 が を参照した場合、つまりストア toが完了したことを意味し、ストア toも完了している必要があるため、必要があります。xya==1b==0xyc==1yxd==1
実際には、std::memory_order_seq_cstどこでも使用すると、コンパイラとプロセッサのアーキテクチャに応じて、ロードまたはストア、またはその両方に追加のオーバーヘッドが追加されます。たとえば、x86 プロセッサの一般的な手法は、必要な順序の保証を提供するためにストアのXCHG命令ではなくMOV命令を使用することですが、プレーンの場合は十分です。より緩和されたメモリ アーキテクチャを備えたシステムでは、単純なロードとストアの保証が少ないため、オーバーヘッドが大きくなる可能性があります。std::memory_order_seq_cststd::memory_order_releaseMOV
メモリの順序付けは難しいです。私は自分の著書の中で、ほぼ 1 つの章全体をそれに当てはめました。