最近、マルチスレッド コードを同期し、コードの並べ替えを回避する方法として、メモリ フェンスとバリアについて読んでいます。
私は通常、Linux OS の下で C++ で開発を行っており、boost
ライブラリを大量に使用していますが、それに関連するクラスを見つけることができません。フェンスのメモリバリアがブーストに存在するかどうか、または同じ概念を実現する方法があるかどうか知っていますか? そうでない場合、どの良いライブラリを見ることができますか?
最近、マルチスレッド コードを同期し、コードの並べ替えを回避する方法として、メモリ フェンスとバリアについて読んでいます。
私は通常、Linux OS の下で C++ で開発を行っており、boost
ライブラリを大量に使用していますが、それに関連するクラスを見つけることができません。フェンスのメモリバリアがブーストに存在するかどうか、または同じ概念を実現する方法があるかどうか知っていますか? そうでない場合、どの良いライブラリを見ることができますか?
ブーストにはまだ低レベルのメモリバリアはありませんが、それらを提供する提案された boost.atomic ライブラリがあります。
__sync_synchronize()
コンパイラは、gccや_mm_mfence()
Visual Studioなどの組み込み関数またはライブラリ関数として独自のものを提供します。
C++0x ライブラリは、std::atomic_thread_fence
. V4.4 以降、gcc はさまざまな形式の C++0x アトミックを提供していますが、V4.4 も V4.5 もこの形式のフェンスを含んでいません。私の (商用)just::thread
ライブラリは、g++ 4.3 と 4.4、および Microsoft Visual Studio 2005、2008、および 2010 のフェンスを含む、C++0x アトミックの完全な実装を提供します。
メモリバリアが必要な場所は、SMP環境でカーネル同期メカニズムの使用を 回避する場合です。通常はパフォーマンス上の理由からです。
データコヒーレンスの危険を防ぐために、カーネル同期操作(セマフォのシグナリング、ミューティスのロックとロック解除など)とコンテンツの切り替えには暗黙のメモリバリアがあります。
私は(適度に)ポータブルメモリバリアの実装(ARMおよびx86)が必要であることに気づきました。また、Linuxソースツリーがこれに最適なソースであることがわかりました。Linuxにはmb()
、rmb()
およびwmb()
マクロのSMPバリアントがあります。これは、一部のプラットフォームでは、非SMPバリアントよりも具体的な(そして場合によってはより安価な)障壁になります。
これは、x86、特にARMでは問題にならないようですが、両方が同じ方法で実装されています。
これは私がLinuxヘッダーファイルからまとめたものです(ARMv7および非古代のx86 / x64プロセッサに適しています)
#if defined(__i386__ ) || defined(__x64__)
#define smp_mb() asm volatile("mfence":::"memory")
#define smp_rmb() asm volatile("lfence":::"memory")
#define smp_wmb() asm volatile("sfence" ::: "memory")
#endif
#if defined(__arm__)
#define dmb() __asm__ __volatile__ ("dmb" : : : "memory")
#define smp_mb() dmb()
#define smp_rmb() dmb()
#define smp_wmb() dmb()
#endif
当然のことながら、メモリバリアに手を出すと、結果として生じるコードをテストすることが事実上不可能になるという付随するリスクがあり、結果として生じるバグはあいまいで、競合状態を再現するのが困難になります:/
ちなみに、Linuxカーネルのドキュメントにはメモリバリアの非常に優れた説明があります。
クラス/コンセプトはありますがboost::barrier
、少しレベルが高いです。そういえば、なんで低レベル結界が必要なの?同期プリミティブで十分でしょう。また、必要に応じて、他の下位レベルのプリミティブを介して直接的または間接的にメモリバリアを使用する必要があります。
それでも低レベルの実装が必要だと思われる場合は、バリアを実装するクラスやライブラリがないことを私は知っていますが、Linux カーネルには実装固有のコードがいくつかあります。mb()
、rmb()
またはwmb()
で検索しinclude/asm-{arch}/system.h
ます。