MemoryBarrier
(MSVC)と_mm_mfence
(複数のコンパイラでサポートされている)の両方がハードウェアメモリフェンスを提供し、プロセッサがフェンスを越えて読み取りと書き込みを移動するのを防ぎます。
主な違いは、MemoryBarrierにはx86、x64、およびIA64のプラットフォーム固有の実装があるのに対し、_mm_mfenceは特にmfence
SSE2命令を使用するため、常に使用できるとは限らないことです。
x86とx64では、MemoryBarrierはそれぞれxchg
とで実装されておりlock or
、これはmfenceよりも高速であるという主張をいくつか見ました。しかし、私自身のベンチマークは反対を示しているので、明らかにそれはプロセッサモデルに大きく依存しています。
もう1つの違いは、mfenceは非一時的なストア/ロード(movntq
など)の注文にも使用できることです。
GCCには__sync_synchronize
、ハードウェアフェンスを生成するものもあります。
asm volatile ("" : : : "memory")
GCCおよび_ReadWriteBarrier
MSVCでは、コンパイラレベルのメモリフェンスのみが提供され、コンパイラがメモリアクセスを並べ替えることができなくなります。これは、プロセッサが自由に並べ替えを実行できることを意味します。
コンパイラフェンスは通常、ある種の暗黙的なハードウェアフェンスを持つ操作と組み合わせて使用されます。たとえば、x86 / x64では、すべてのストアにリリースフェンスがあり、ロードには取得フェンスがあるため、load-acquireとstore-releaseを実装する場合はコンパイラフェンスが必要です。