std::memory_order_acquire
との私の理解は次のstd::memory_order_release
とおりです。
取得とは、取得フェンスの後に出現するメモリ アクセスをフェンスの前に並べ替えることができないことを意味します。
リリースとは、リリース フェンスの前に出現するメモリ アクセスをフェンスの後に並べ替えることができないことを意味します。
私が理解できないのは、特に C++11 アトミック ライブラリでは、取得フェンスがロード操作に関連付けられ、リリース フェンスがストア操作に関連付けられている理由です。
明確にするために、C++11<atomic>
ライブラリでは、メモリ フェンスを次の 2 つの方法で指定できます。
x.load(std::memory_order_acquire);
または、次std::memory_order_relaxed
のようにフェンスを個別に使用して指定することもできます。
x.load(std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_acquire);
私が理解していないのは、上記の acquire と release の定義を考えると、なぜ C++11 がacquireをloadに、releaseをstoreに関連付けるのかということです。はい、取得/ロードとリリース/ストアを使用してスレッド間で同期する方法を示す多くの例を見てきましたが、一般的には、取得フェンス (ステートメントの後のメモリの並べ替えを防ぐ) とリリースのアイデアのようです。フェンス (ステートメントの前にメモリの並べ替えを防止する) は、ロードとストアの考え方と直交しています。
では、たとえば、コンパイラが次のように言わないのはなぜですか。
x.store(10, std::memory_order_acquire);
memory_order_relaxed
を使用してから別のステートメントを使用することで上記を達成できるatomic_thread_fence(memory_order_acquire)
ことはわかっていますが、もう一度、ストアを直接使用できないのはなぜmemory_order_acquire
ですか?
これの考えられるユースケースは、他のスレッドに影響を与える可能性のある他のステートメントが実行される前にx = 10
、ストア、たとえばが発生するようにしたい場合です。