明示的なメモリ フェンスを使用するとはどういう意味ですか?
5 に答える
パフォーマンスを向上させるために、最近の CPU は、使用可能なシリコン (メモリの読み取り/書き込みを含む) を最大限に活用するために、命令を順不同で実行することがよくあります。ハードウェアが命令の整合性を強制するため、単一の実行スレッドでこれに気付くことはありません。ただし、複数のスレッドや、揮発性メモリを使用する環境 (メモリ マップド I/O など) では、これにより予期しない動作が発生する可能性があります。
メモリ フェンス/バリアは、メモリの読み取り/書き込みが予期した順序で行われることを意味する命令のクラスです。たとえば、「完全なフェンス」とは、フェンスの前のすべての読み取り/書き込みが、フェンスの後の読み取り/書き込みの前にコミットされることを意味します。
メモ メモリ フェンスはハードウェアの概念です。高水準言語では、mutex とセマフォの扱いに慣れています。これらは、低レベルでメモリ フェンスを使用して実装することができ、メモリ バリアを明示的に使用する必要はありません。メモリ バリアを使用するには、ハードウェア アーキテクチャを慎重に検討する必要があり、アプリケーション コードよりもデバイス ドライバでよく見られます。
CPU の並べ替えは、コンパイラの最適化とは異なりますが、アーティファクトは似ています。望ましくない動作 (C での volatile キーワードの使用など) が発生する可能性がある場合は、コンパイラが命令を並べ替えるのを停止するために、別の手段を講じる必要があります。
私の答えを別の質問にコピーすると、プロセッサがコードを最適化するために行ういくつかのトリックは何ですか? :
最も重要なものは、メモリ アクセスの並べ替えです。
メモリ フェンスやシリアル化命令がない場合、プロセッサはメモリ アクセスを自由に並べ替えることができます。一部のプロセッサ アーキテクチャには、並べ替え可能な量に制限があります。Alpha は最も弱いことで知られています (つまり、最も並べ替えることができるものです)。
Linux カーネルのソース ドキュメント ( Documentation/memory-barriers.txt ) には、この件に関する非常に適切な説明が記載されています。
ほとんどの場合、コンパイラまたは標準ライブラリのロック プリミティブを使用するのが最善です。これらは十分にテストされており、必要なすべてのメモリバリアが適切に配置されている必要があり、おそらく非常に最適化されています (ロックプリミティブの最適化はトリッキーです。専門家でさえ間違っている場合があります)。
私の経験では、複数のスレッド間でメモリ アクセスを同期するための命令 (明示的または暗黙的) であるメモリ バリアを指します。
この問題は、最新のアグレッシブなコンパイラー (命令を並べ替える驚くほどの自由がありますが、通常はスレッドについて何も知らない) と最新のマルチコア CPU の組み合わせで発生します。
この問題の適切な紹介は、「「ダブルチェック ロックが壊れている」宣言」です。多くの人にとって、ドラゴンの存在は目覚ましでした。
暗黙的なフル メモリ バリアは、通常、プラットフォーム スレッド同期ルーチンに含まれており、そのコアをカバーしています。ただし、ロックフリー プログラミングとカスタムの軽量同期パターンの実装では、多くの場合、バリアのみ、または一方向バリアのみが必要です。
メモリ バリア (メンバーまたはメモリ フェンスとも呼ばれます) は、バリア命令の前後に発行されるメモリ操作に対して、中央処理装置 (CPU) に順序制約を強制させる命令のクラスです。
CPU はパフォーマンスの最適化を採用しているため、メモリのロードやストア操作など、順不同で実行される可能性があります。メモリ操作の並べ替えは通常、1 つの実行スレッド内では気付かれませんが、慎重に制御しない限り、並行プログラムやデバイス ドライバーで予期しない動作が発生します。順序制約の正確な性質はハードウェアに依存し、アーキテクチャのメモリ モデルによって定義されます。一部のアーキテクチャは、さまざまな順序制約を適用するための複数のバリアを提供します。
メモリ バリアは通常、複数のデバイスで共有されるメモリ上で動作する低レベルのマシン コードを実装するときに使用されます。このようなコードには、マルチプロセッサ システム上の同期プリミティブとロックフリー データ構造、およびコンピュータ ハードウェアと通信するデバイス ドライバが含まれます。
memory fence
( ) は、複数のスレッドmemory barrier
を同期するための一種のロックフリー メカニズムです。シングルスレッド環境では、並べ替えは安全です。
問題は、順序付け、共有リソース、およびキャッシングです。プロセッサまたはコンパイラは、最適化のためにプログラム命令 (プログラマ順序) を並べ替えることができます。マルチスレッド環境で副作用が発生します。そのためmemory barrier
、プログラムが適切に動作することを保証するために導入されました。遅くなりますが、このタイプの問題は修正されます