最近、アトミックと C++0x についていくつか質問しました。コードを変換する前に、順序付けのセマンティクスを理解しておきたいと思います。このプレ0xコードがあるとしましょう:
atomic_int a = 0;
some_struct b;
Thread A:
b = something;
atomic_store_fence();
a = 1;
Thread B:
if( a == 1 )
{
atomic_load_fence();
proc(b);
}
現在のコンパイラ/プラットフォームがatomic_int
、atomic_store_fence
およびに提供するものを使用しますatomic_load_fence
。
C++0x では、コードにはいくつかの可能な形式があります。2つの明白なものは次のように見えます:
atomic<int> a = ATOMIC_VAR_INIT(0);
some_struct b;
Thread A:
b = something;
atomic_thread_fence( memory_order_release );
a.store( 1, memory_order_relaxed );
Thread B:
if( a.load( memory_order_relaxed ) == 1)
{
atomic_thread_fence( memory_order_acquire );
proc(b);
}
また
Thread A:
b = something;
a.store( 1, memory_order_release );
Thread B:
if( a.load( memory_order_acquire ) == 1)
{
proc(b);
}
アトミックなストアリリース/ロード取得シーケンスは、明示的なフェンスバージョンと同じメモリ順序の意味を持つ同期イベントであると読んで正しいですか? つまり、2番目のバージョンは正しいですか?
正しければ、2 番目のものは必要以上にフェンスを発行しますa != 1
。標準のセクション 29.8-3 は、アトミックとフェンスを組み合わせて使用できることを示しています。それでは、以下は正しく合理的な実装ですか?
Thread A:
b = something;
a.store( 1, memory_order_release );
Thread B:
if( a.load( memory_order_relaxed ) == 1 )
{
atomic_thread_fence( memory_order_acquire );
proc(b);
}