MemoryBarrier
(MSVC)と_mm_mfence
(複数のコンパイラでサポートされています)は、ハードウェアメモリフェンスを提供し、プロセッサがフェンスを介して読み書きを移動できないようにします。
主な違いは、MemoryBarrierにx86、x64、IA64向けのプラットフォーム固有の実装があり、_mm_mfenceは具体的にはmfence
SSE2命令を使用するため、常に利用できるとは限りません。
x86およびx64の場合MemoryBarrierはそれぞれxchg
とlock or
で実装されていますが、これはmfenceより高速であるといういくつかの主張を見てきました。しかし、私自身のベンチマークは逆を示しているので、明らかにプロセッサモデルに非常に依存しています。
mfenceは、非一時的なストア/ロードの注文にも使用できます(movntq
など)。
GCCには、ハードウェアフェンスを生成する__sync_synchronize
もあります。
asm volatile ("" : : : "memory")
とMSVCの_ReadWriteBarrier
は、コンパイラレベルのメモリフェンスを提供するだけであり、コンパイラによるメモリアクセスの並べ替えの妨げになります。つまり、プロセッサはまだ並べ替えを自由に行うことができます。
コンパイラフェンスは、一般に、何らかの暗黙的なハードウェアフェンスを持つ操作と組み合わせて使用されます。例えば。 x86/x64ではすべてのストアにリリースフェンスがあり、ロードには取得フェンスがあるため、load-acquireとstore-releaseを実装するときにはコンパイラーフェンスが必要です。
あなたはC++ 11s 'atomic_thread_fence'を忘れました – Grizzly
これは、これが導いていることです...私たちは整数型のための独自の原子テンプレートオブジェクトを持っており、私はC++ 11標準アトミックに切り替えたいと思っています。これを行う前に、両方が実際にどのように機能するかについての基本的な実装を理解したいと思います。 – AJG85