web-dev-qa-db-ja.com

メモリフェンスとは何ですか?

明示的なメモリフェンスを使用するとはどういう意味ですか?

103
yesraaj

パフォーマンスを向上させるために、最新のCPUは多くの場合、使用可能なシリコン(メモリの読み取り/書き込みを含む)を最大限に活用するために、誤った命令を実行します。ハードウェアは命令の整合性を強制するため、実行の単一スレッドでこれに気付くことはありません。ただし、複数のスレッドまたは揮発性メモリ(たとえば、メモリマップI/O)を使用する環境では、これにより予測できない動作が発生する可能性があります。

メモリフェンス/バリアは、メモリの読み取り/書き込みが期待する順序で発生することを意味する命令のクラスです。たとえば、「フルフェンス」は、フェンスの前のすべての読み取り/書き込みが、フェンスの後の読み取り/書き込みの前にコミットされることを意味します。

メモリフェンスはハードウェアの概念であることに注意してください。高レベルの言語では、ミューテックスとセマフォの処理に慣れています。これらは低レベルのメモリフェンスを使用して実装することができ、メモリバリアの明示的な使用は必要ありません。メモリバリアを使用するには、ハードウェアアーキテクチャを慎重に検討する必要があり、アプリケーションコードよりもデバイスドライバーでよく見られます。

CPUの並べ替えは、コンパイラの最適化とは異なりますが、アーティファクトは似ている場合があります。望ましくない動作を引き起こす可能性がある場合(Cでvolatileキーワードを使用するなど)、コンパイラーによる命令の並べ替えを停止するには、個別の対策を講じる必要があります。

99
Gwaredd

my answer を別の質問にコピーします プロセッサがコードを最適化するために行うトリックは何ですか?

最も重要なのは、メモリアクセスの並べ替えです。

メモリフェンスまたはシリアル化命令がない場合、プロセッサはメモリアクセスを自由に並べ替えることができます。一部のプロセッサアーキテクチャでは、並べ替え可能な量に制限があります。アルファは、最も弱い(つまり、最も順序を変更できる)ことで知られています。

件名の非常に良い扱いは、Linuxカーネルソースドキュメントの Documentation/memory-barriers.txt にあります。

ほとんどの場合、コンパイラまたは標準ライブラリのロックプリミティブを使用することをお勧めします。これらは十分にテストされ、必要なすべてのメモリバリアが適切に配置されている必要があり、おそらく非常に最適化されています(ロックプリミティブの最適化は注意が必要です。

15
CesarB

私の経験では、複数のスレッド間でメモリアクセスを同期するための命令(明示的または暗黙的)である memory barrier を指します。

この問題は、最新のアグレッシブなコンパイラ(命令を並べ替える驚くべき自由がありますが、通常はスレッドについては何も知りません)と最新のマルチコアCPUの組み合わせで発生します。

この問題の良い紹介は、「 「ダブルチェックロックが壊れています」宣言 」です。多くの人にとって、それはドラゴンがいるというモーニングコールでした。

暗黙の完全なメモリバリアは、通常、プラットフォームスレッド同期ルーチンに含まれ、そのコアをカバーします。ただし、ロックのないプログラミングとカスタムの軽量同期パターンの実装には、多くの場合、バリアのみ、または一方向のバリアのみが必要です。

6
peterchen

ウィキペディアはすべてを知っています...

Membarまたはメモリフェンスとも呼ばれるメモリバリアは、中央処理装置(CPU)がバリア命令の前後に発行されるメモリ操作に順序付け制約を強制する命令のクラスです。

CPUはパフォーマンスの最適化を採用しており、その結果、メモリのロードやストアの操作など、順不同の実行が発生する可能性があります。メモリ操作の並べ替えは、通常、単一の実行スレッド内では見過ごされますが、慎重に制御されない限り、並行プログラムおよびデバイスドライバーで予期しない動作を引き起こします。順序制約の正確な性質はハードウェアに依存し、アーキテクチャのメモリモデルによって定義されます。一部のアーキテクチャは、異なる順序の制約を強制するための複数の障壁を提供します。

メモリバリアは通常、複数のデバイスで共有されるメモリ上で動作する低レベルのマシンコードを実装するときに使用されます。このようなコードには、マルチプロセッサシステム上の同期プリミティブとロックフリーデータ構造、およびコンピューターハードウェアと通信するデバイスドライバーが含まれます。

1
Omar Kooheji