メモリーバリア
読み:メモリーバリア
外語:memory barrier

 メモリー操作をする命令の実行順序を維持する、プロセッサーの機能。メモリーフェンスとも。
目次

概要
 現在のマイクロプロセッサーは、高速処理のための最適化として、アウトオブオーダー実行を導入するものが多い。この時、命令は並び替えられて処理されるが、この命令にはメモリーのロード命令やストア命令も含まれる。
 この命令の入れ替えは、単一のスレッド内では破綻が生じないように動作するが、マルチスレッド環境では支障が出ることがある。そのような命令があった場合は、それらの命令の影響が全て完了した後で、後続の命令が実行されることを保証する動作のシーケンスが必要となる。
 そこでこのような場合は、手動で(プログラマーによるプログラムの記述によって)アウトオブオーダー実行を一時的に抑止する必要があり、このような目的のための動作をメモリーバリアという。

実装

x86

専用命令
 x86の場合は、次の3命令が用意されている。
 lfence (0F AE /5)
 mfence (0F AE /6)
 sfence (0F AE /7)
 なお、lfenceは50サイクル強、sfenceは50サイクル弱程度の実行レイテンシーがあるが、mfenceは130サイクル程度を要し、非常に遅い命令の一つである。
 例えば変数への代入を終えたあとフラグをセットする処理と、フラグがセットされたら変数を読みだして処理する処理があり、マルチスレッドで動作していたとする。この時、フラグのセットは非常に重要である。
 フラグをセットする側の処理では、変数への代入とフラグのセットの間にsfenceを置き、確実に書き込まれてからフラグがセットされるようにする。
 フラグを確認して処理する側では、フラグ確認と後の処理の間にlfenceを置き、フラグの確認が済む前に後の処理が実行されないようにする。

代用方法
 x86/x64アーキテクチャーにおいては、メモリーアクセスの順序保証が必要な場合でも、殆どの場合は明示的なメモリーバリア命令を使わずに済む。
 C++のstd::atomicの実装においても、基本的には単純なmov命令を発行するだけでよい。ただしstd::memory_order_seq_cstだけはxchg命令か、movの後でmfence命令が必要になる。

ARM
 ARMでは、ISB、DSB、DMBの各命令がある。
 ARMの処理系では、例えば、次のような組み込み関数が用意される。動作は、単にDMB/DSB/ISB命令を発行するだけである。
 また、より新しいバージョンのARM用C/C++コンパイラーでは、内部的にはchar型の引数を取る、次のような組み込み関数がある。
 互換性のため、次のようなdefine文が定義されている。
#define __ISB() __isb(0xf);
#define __DSB() __dsb(0xf);
#define __DMB() __dmb(0xf);
 この引数付きの組み込み関数のパラメータは、バリア命令にある4ビットのオプションフィールドにあてられ、オプションで処理中の制限を定義するために使われる。
 命令のオペコードは次の通りである(x=option)。

再検索