5

現在のC++0x ドラフトでは、セクション 29.3.9 および 29.3.10 の 1111 ~ 1112 ページに次の例のように記載されています。

// Thread 1
r1 = y.load(memory_order_relaxed);
x.store(1, memory_order_relaxed);

// Thread 2
r2 = x.load(memory_order_relaxed);
y.store(1, memory_order_relaxed);

r1 = r2 = 1各スレッドの操作が緩和され、無関係なアドレスに送信されるため、結果は可能です。ここで、私の質問は、次の (同様の) 例の考えられる結果についてです。

// Thread 1
r1 = y.load(memory_order_acquire);
x.store(1, memory_order_release);

// Thread 2
r2 = x.load(memory_order_acquire);
y.store(1, memory_order_release);

r1 = r2 = 1この場合、結果はありえないと思います。可能であれば、y のロードは y へのストアと同期します (つまり、前に発生します)。x と同様に、x のロードは x へのストアの前に発生します。ただし、y のロードは、x へのストアの前に順序付けられます (したがって、前に発生します)。これにより、循環的な事前発生関係が作成されますが、これは許可されていないと思います。

4

1 に答える 1

4

コードを読むのと同じように、下に流れるのに時間がかかる場合(または、必要に応じて命令シーケンス)、私の理解では、

  • 取得フェンスは、他のメモリ アクセスがフェンスを越えて下方に移動することを許可しますが、フェンスを越えて上方に移動することはできません
  • リリース フェンスを使用すると、他のメモリ アクセスがフェンスを超えて上方に移動できますが、フェンスを超えて下方に移動することはできません

つまり、次のようなコードがある場合

acquire
// other stuff
release

その場合、メモリアクセスは取得/解放ペアの外側から内側に移動する可能性がありますが、その逆はできません (また、取得/解放ペアを完全にスキップすることもできません)。

問題の最初の例の緩和された一貫性セマンティクスを使用すると、ハードウェアは、ロードの前にストアがメモリ システムに入るようにメモリ アクセスの順序を変更できるため、r1=r2=1 が許可されます。2 番目の例の取得/解放セマンティクスでは、その並べ替えが防止されるため、r1=r2=1 は不可能です。

于 2010-05-26T12:35:49.303 に答える