次のように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);
私は、取得の上記の定義を与え、解放している理解していない、なぜC++ 11は、具体的取得を関連付けないとの負荷とのリリースとのストア?はい、私はリリース/ストアで取得/負荷をスレッド間で同期するために使用する方法を示す多くの例を見てきましたが、一般的にはフェンスを獲得するという考え方(ステートメントの後にメモリの並べ替えを防ぐ)フェンス(文の前にメモリの順序を変更しないようにする)は、ロードとストアの考え方とは正反対です。
それでは、なぜ、例えば、コンパイラは私が言わせません。
x.store(10, std::memory_order_acquire);
私はmemory_order_relaxed
を使用して上記を達成することができます実現し、その後、別のatomic_thread_fence(memory_order_acquire)
声明が、再び、なぜできmemory_order_acquire
と直接店舗を使用していますか?
x = 10
などのストアがになる前に、の前に他のスレッドに影響する可能性のあるストアが確実に実行されている可能性があります。
、あなたは(取得する準備ができて)共有リソースが消費のために準備ができているかどうかを確認するために、原子を読んで、あなたは、共有リソースを使用する準備ができていることを示すために、原子を書く(へリソースを解放する)。アトミックガーディングがチェックされる前に共有リソースの読み込みを望んではいけません。アトミックが書き込まれた後、解放を示す共有リソースの初期化を望んではいけません。 –
この例では、 'atomic_thread_fence(std :: memory_order_acquire)'のみが真のフェンスです。 _標準の「** 1.10:5マルチスレッド実行とデータ競合[intro.multithread] **」を参照してください(n3797のドラフトを引用しています)_ "関連付けられたメモリ位置のない同期操作はフェンスであり、これとは対照的に、 'x.load(std :: memory_order_acquire)'は_atomic操作であり、 'x'で_acquire_操作を実行すると、_synchronization operation_値がストアに一致した場合_release_をxに格納します。 – amdn
はじめに、標準(ドラフトn3797)では、取得操作をロードに制限したり、ストア操作をストアに解放することはできません。それは残念です。 memory_order_acquire、memory_order_acq_rel、およびmemory_order_seq_cst:ロード操作が、影響を受けたメモリ位置で取得操作を実行します。 "_ and _" memory_order_release ** 29.3:1 Order and consistency [atomics.order] **に移動する必要があります。 、memory_order_acq_rel、およびmemory_order_seq_cst:ストア操作は、影響を受けたメモリ位置で解放操作を実行します。 "_ – amdn