アトミック操作の 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==1
b==0
c==1
d==0
すべてのメモリ順序が に変更された場合、ストアとstd::memory_order_seq_cst
の間の順序が強制されます。したがって、スレッド 3 がandを参照した場合、それはストア to がストア to の前にある必要があることを意味し、スレッド 4 が を参照した場合、つまりストア toが完了したことを意味し、ストア toも完了している必要があるため、必要があります。x
y
a==1
b==0
x
y
c==1
y
x
d==1
実際には、std::memory_order_seq_cst
どこでも使用すると、コンパイラとプロセッサのアーキテクチャに応じて、ロードまたはストア、またはその両方に追加のオーバーヘッドが追加されます。たとえば、x86 プロセッサの一般的な手法は、必要な順序の保証を提供するためにストアのXCHG
命令ではなくMOV
命令を使用することですが、プレーンの場合は十分です。より緩和されたメモリ アーキテクチャを備えたシステムでは、単純なロードとストアの保証が少ないため、オーバーヘッドが大きくなる可能性があります。std::memory_order_seq_cst
std::memory_order_release
MOV
メモリの順序付けは難しいです。私は自分の著書の中で、ほぼ 1 つの章全体をそれに当てはめました。