1

共有変数を読み取るスレッドは最初に を呼び出し、共有変数に書き込むスレッドは後でflushOpenMP を呼び出して、共有変数をメイン メモリとキャッシュの同期状態に保つ必要があります。関数はどの方向にフラッシュするかをflushどのように認識しますか? flush両方の変数 (メイン メモリまたはキャッシュ) のどちらが新しいかを知る必要があります。OSまたはCPUが何らかの形でこれを処理していると思いますが、よくわかりません。誰か知っていますか?

4

2 に答える 2

1

flushは関数ではありません。OpenMPコンパイラ ディレクティブです。これは、コンパイラが実行可能コードを生成する方法に影響を与え、フラッシュ セット内のすべての最適化された変数 (CPU レジスタまたはその他の明示的にプログラム可能なキャッシュ/スレッド ローカル メモリに格納されている) の値を同期するように指示します。これは、ストレージ修飾子がコード生成に及ぼす影響に似ていますが、volatileより制限されたポイント ローカル効果があります。

それはどのように機能しますか?ソース コードの解析中に、コンパイラはステートメントの流れと、それらのステートメントによって影響を受けるデータ (変数) を分析します。その結果、コンパイラはコードから実行グラフとデータ依存グラフを作成します。各変数の値がどこでどのように使用されているか、どのコード ブロックの実行がどの変数に影響するかを正確に認識します。次に、コンパイラはグラフを単純化してコードを最適化し、CPU レジスタを使用して中間値を格納するか、別のレジスタを使用してより高速なスレッド アドレス指定可能なローカル メモリを使用することにより、コストのかかるメモリ操作の数を削減しようとします。のflushディレクティブは、実行グラフに特別なポイントを追加します。このポイントでは、コンパイラがスレッドのメモリ ビュー (レジスタ変数とローカル メモリ変数) をグローバル共有メモリと明示的に同期する必要があります。コンパイラは最初に依存関係グラフを構築しているため、フラッシュセット内のどの変数が変更され、共有メモリに書き込む必要があるかを正確に認識しています。フラッシュ セット内の他のすべての変数は、共有メモリから読み取る必要があります。

したがって、あなたの質問に対する答えは、通常、flushOS ではなくディレクティブを処理するのはコンパイラであるということです。ただし、明示的にプログラム可能なキャッシュ/ローカル メモリを備えたシステムなどで、コンパイラは実際にフラッシュを実装するために OS を呼び出す場合があります。ただし、OpenMP は抽象的な標準であり、多くの異なるハードウェア プラットフォームに実装できること、およびそれらのプラットフォームの一部は、OpenMP の抽象化をより効率的に実装するのに役立つ特定のハードウェアを提供していることにも注意する必要があります (例: IBM の Blue Gene/ Q はそのような多くの機能を提供します)。

于 2013-02-15T12:33:01.290 に答える
-1

共有変数の同期を維持するためにflushを呼び出す必要はありません。ハードウェア(CPU)はキャッシュされたメモリを追跡し、競合するアクセスがある場合、キャッシュがCPUによってフラッシュされるため、プログラムの速度が低下します。

私はflushディレクティブを条件付きバリアのように理解しています。同じ変数を含むフラッシュは、効果を発揮するために少なくとも2つのスレッドで検出される必要があります。このディレクティブが共通の変数aを持つ2つのスレッドによって満たされる場合、それらが変更した場合、それらは変更をメモリに書き戻します(ローカル変数またはレジスタに保持するのではなく)、そして私は障壁があると思います両方のスレッドが続行する前にそのポイントに到達するため。フラッシュ後に変数aが使用された場合、それはメモリから再読み取りされます。

于 2013-02-15T11:01:51.170 に答える