メモリーバリア

読み:メモリーバリア
外語:memory barrier 英語
品詞:名詞

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

目次

現在のマイクロプロセッサーは、高速処理のための最適化として、アウトオブオーダー実行を導入するものが多い。この時、命令は並び替えられて処理されるが、この命令にはメモリーのロード命令やストア命令も含まれる。

この命令の入れ替えは、単一のスレッド内では破綻が生じないように動作するが、マルチスレッド環境では支障が出ることがある。そのような命令があった場合は、それらの命令の影響が全て完了した後で、後続の命令が実行されることを保証する動作のシーケンスが必要となる。

そこでこのような場合は、手動で(プログラマーによるプログラムの記述によって)アウトオブオーダー実行を一時的に抑止する必要があり、このような目的のための動作をメモリーバリアという。

x86

専用命令

x86の場合は、次の3命令が用意されている。

lfence (0F AE /5)

mfence (0F AE /6)

sfence (0F AE /7)

なお、lfenceは50サイクル強、sfenceは50サイクル弱程度の実行レイテンシーがあるが、mfenceは130サイクル程度を要し、非常に遅い命令の一つである。

  • lfence命令をプログラムに挿入すると、lfence命令より後ろのロード命令が、lfence命令より先に実行されることを防ぐ
  • sfence命令をプログラムに挿入すると、sfence命令より前のストア操作が完了するのを待つ
  • mfence命令は、lfenceとsfenceを足したもの

例えば変数への代入を終えたあとフラグをセットする処理と、フラグがセットされたら変数を読みだして処理する処理があり、マルチスレッドで動作していたとする。この時、フラグのセットは非常に重要である。

フラグをセットする側の処理では、変数への代入とフラグのセットの間にsfenceを置き、確実に書き込まれてからフラグがセットされるようにする。

フラグを確認して処理する側では、フラグ確認と後の処理の間にlfenceを置き、フラグの確認が済む前に後の処理が実行されないようにする。

代用方法

x86/x64アーキテクチャーにおいては、メモリーアクセスの順序保証が必要な場合でも、殆どの場合は明示的なメモリーバリア命令を使わずに済む。

C++のstd::atomicの実装においても、基本的には単純なmov命令を発行するだけでよい。ただしstd::memory_order_seq_cstだけはxchg命令か、movの後でmfence命令が必要になる。

ARM

ARMでは、ISB、DSB、DMBの各命令がある。

  • ISB ‐ 命令同期バリア
  • DSB ‐ データ同期バリア
  • DMB ‐ データメモリーバリア

ARMの処理系では、例えば、次のような組み込み関数が用意される。動作は、単にDMB/DSB/ISB命令を発行するだけである。

  • __ISB(void)
  • __DSB(void)
  • __DMB(void)

また、より新しいバージョンのARM用C/C++コンパイラーでは、内部的にはchar型の引数を取る、次のような組み込み関数がある。

  • __isb(<option>)
  • __dsb(<option>)
  • __dmb(<option>)

互換性のため、次のようなdefine文が定義されている。

#define __ISB() __isb(0xf);
#define __DSB() __dsb(0xf);
#define __DMB() __dmb(0xf);

この引数付きの組み込み関数のパラメータは、バリア命令にある4ビットのオプションフィールドにあてられ、オプションで処理中の制限を定義するために使われる。

命令のオペコードは次の通りである(x=option)。

  • ISB ‐ F57FF06x / F3BF 8F6x
  • DSB ‐ F57FF04x / F3BF 8F4x
  • DMB ‐ F57FF05x / F3BF 8F5x

コメントなどを投稿するフォームは、日本語対応時のみ表示されます


KisoDic通信用語の基礎知識検索システム WDIC Explorer Version 7.04a (27-May-2022)
Search System : Copyright © Mirai corporation
Dictionary : Copyright © WDIC Creators club