2

OpenMP スレッドを使用している間、

  1. 各スレッドは、独自の一連のプライベート変数を宣言できます。各スレッドにプライベートなデータのフェッチは、すべてのスレッドに表示されるデータのフェッチよりも待ち時間が短いと仮定するのは正しいですか。つまり、スレッドローカル変数はキャッシュされていますか?

  2. 各スレッドが、のようなスレッド プライベート STL データ コンテナーを使用したいとしますstd::vector。シングル スレッドの C++ コードでは、データstd::vectorはヒープに格納されます。マルチスレッドの場合はどうですか?スレッド プライベート std::vectors のデータはまだヒープに格納されていますか?

4

2 に答える 2

5

NUMA マシンを使用していない限り、メモリは均一です。

各スレッドにプライベートなデータのフェッチは、すべてのスレッドに表示されるデータのフェッチよりも待ち時間が短いと仮定するのは正しいですか。

スレッド ローカル ストレージは、すべてのスレッドから見えるメモリより本質的に「高速」ではありません。ただし、1 つのスレッドによってのみ使用されるメモリは、単一のスレッドによってのみアクセスされるため、キャッシュ コヒーレンシの影響を受ける可能性は低くなります。

つまり、スレッド ローカル変数はキャッシュされていますか?

必ずしも。そして、CPU キャッシュに収まらない場合は、そうではありません。共有データが複数のコアのキャッシュに同時に存在することも可能です。

マルチスレッドのケースはどうですか?スレッド プライベート std::vectors のデータはまだヒープに格納されていますか?

はい、スレッドの数に関係なく、ヒープになります。

于 2012-07-15T16:09:24.270 に答える
3

プライベート変数と共有変数は、広く使用されている事実上すべての OpenMP ランタイムで異なる方法で実装されています。

private自動変数は実行中の各スレッドのスタックに存在し、threadprivate変数は TLS に存在します。自動プライベート変数は、通常どおり登録するように最適化することもできます。

shared並列領域の変数は通常、各スレッド関数への引数としてアドレスによって渡される構造体として実装され、その後、追加のポインター逆参照を使用して各共有変数にアクセスします。さらに、一部のコンパイラは共有変数を暗黙的に扱いvolatile、ロード/更新/ストア命令の全スペクトルを発行しますが、OpenMP は、特定の同期まで、異なるスレッド内の共有変数の可視値間のある程度の不一致を許容する緩和されたメモリ モデルを提供します。そのようなポイントの 1 つは明示的なflushディレクティブです (依然としてflush最も広く誤解されている OpenMP 機能であり、言語メーカーでさえ、標準ドキュメントでその使用法に関する例を入手できません)。

マルチスレッドの場合のヒープへのデータの割り当てに関しては、ほとんどのヒープ実装がリンクされたリストまたは同様のデータ構造を使用するため、ヒープ操作は本質的にシリアル化されます。また、通常のアロケータは、異なるスレッドによって割り当てられたデータがキャッシュ ラインを共有することになるかどうか、およびこれが誤った共有と関連するパフォーマンスの低下につながるかどうかを気にしません。hoardptmallocumem、などの特殊なマルチスレッド アロケータがありtcmalloc、より多くのメモリを使用してこれらの問題に対処しようとします。それらの一部 (例tcmalloc) も NUMA 対応です。tcmallocドキュメントは、STLコンテナがデフォルトのアロケータの代わりにそのアロケータを使用するようにするために何らかの「魔法」を行うと主張していますが、私は両方tcmallocとC ++のヘビーユーザーではないので同意できません。

NUMA システムで実行する場合に考慮すべきことの 1 つは、スレッド バインディングです。一部の OpenMP ランタイムには、コアへのスレッドのバインドを制御するための規定が既に含まれており、言語委員会で現在議論されているように、今後の OpenMP 標準には、バインディング プロパティを指定するための標準フレームワークが含まれる可能性が最も高いでしょう。

于 2012-07-15T18:23:25.990 に答える