2012-01-12 5 views
27

私はこれに関しては初心者です。誰も次のメモリバリアの違いを簡単に説明できますか?アトミックのためのC++メモリバリアー

  • MemoryBarrier();
  • フェンス_mm_mfence();
  • インラインアセンブリasm volatile ("" : : : "memory");
  • 簡単な説明がされていない場合_ReadWriteBarrier();

固有の優れた記事や書籍だろうへのリンクおそらく私はそれをまっすぐに助ける。これまでは、これらの呼び出しをラッピングする他の人が書いたオブジェクトを使っても問題ありませんでしたが、基本的にはメモリバリアを実装する方法が複数あります。

+4

あなたはC++ 11s 'atomic_thread_fence'を忘れました – Grizzly

+0

これは、これが導いていることです...私たちは整数型のための独自の原子テンプレートオブジェクトを持っており、私はC++ 11標準アトミックに切り替えたいと思っています。これを行う前に、両方が実際にどのように機能するかについての基本的な実装を理解したいと思います。 – AJG85

答えて

28

MemoryBarrier(MSVC)と_mm_mfence(複数のコンパイラでサポートされています)は、ハードウェアメモリフェンスを提供し、プロセッサがフェンスを介して読み書きを移動できないようにします。

主な違いは、MemoryBarrierにx86、x64、IA64向けのプラットフォーム固有の実装があり、_mm_mfenceは具体的にはmfence SSE2命令を使用するため、常に利用できるとは限りません。

x86およびx64の場合MemoryBarrierはそれぞれxchglock orで実装されていますが、これはmfenceより高速であるといういくつかの主張を見てきました。しかし、私自身のベンチマークは逆を示しているので、明らかにプロセッサモデルに非常に依存しています。

mfenceは、非一時的なストア/ロードの注文にも使用できます(movntqなど)。

GCCには、ハードウェアフェンスを生成する__sync_synchronizeもあります。

asm volatile ("" : : : "memory")とMSVCの_ReadWriteBarrierは、コンパイラレベルのメモリフェンスを提供するだけであり、コンパイラによるメモリアクセスの並べ替えの妨げになります。つまり、プロセッサはまだ並べ替えを自由に行うことができます。

コンパイラフェンスは、一般に、何らかの暗黙的なハードウェアフェンスを持つ操作と組み合わせて使用​​されます。例えば。 x86/x64ではすべてのストアにリリースフェンスがあり、ロードには取得フェンスがあるため、load-acquireとstore-releaseを実装するときにはコンパイラーフェンスが必要です。

+0

完璧!ありがとう、それは多くの助けとなりました。 – AJG85

3

フェンスのハードウェアレベルのセマンティクスについては、私の答えhereを参照してください。何も言及されていないのは、ロード、ストア、またはロードの並べ替えが(コンパイルレベルとハードウェアレベルの両方で)フェンスにまたがる&ストア(フェンスに応じて)の並べ替えを防ぐことです。

関連する問題