OpenMPを使用してCプログラムを並列化しようとしています。
私はもっと知りたいです:
私の知る限り、違いはthreadprivateのグローバルスコープと、並列領域間で保持される値です。いくつかの例で、コードの一部に民営化する必要のあるグローバル/静的変数が含まれている場合、これらの変数はthreadprivateリストに含まれ、それらの初期値は-を使用してプライベートコピーにコピーされることがわかりました。 コピーイン。
ただし、private句を使用してグローバル/静的変数を処理することを妨げるルールはありますか?おそらく実装の詳細はありますか?
OpenMP3.0仕様で説明が見つかりませんでした。
あなたが覚えなければならない最も重要な違い:
private
変数はリージョンに対してローカルであり、ほとんどの場合スタックに配置されます。変数のプライバシーの存続期間は、データスコープ句で定義された期間です。すべてのスレッド(マスタースレッドを含む)は、元の変数のプライベートコピーを作成します(新しい変数は、元の変数にストレージに関連付けられなくなります)。
一方、threadprivate
変数は、ヒープまたはスレッド)に配置される可能性があります。ローカルストレージ(スレッドに対してローカルなグローバルメモリと見なすことができます)。 threadprivate
変数は、リージョン間で存続します(いくつかの制限によって異なります)。マスタースレッドは元の変数を使用し、他のすべてのスレッドは元の変数のプライベートコピーを作成します(マスター変数は引き続き元の変数にストレージに関連付けられています)。
さらにトリッキーな違いもあります。
private
として定義された変数は、構成に入るときはスレッドごとに未定義であり、対応する共有変数は、並列構成が終了するときに未定義です。 private
ポインタの初期ステータスは未定義です。
ただし、threadprivate
句が指定されていない限り、copyin
共通ブロック内のデータは、最初の並列領域へのエントリ時に未定義であると見なす必要があります。共通ブロックがthreadprivate
ディレクティブに現れると、各スレッドコピーは最初に使用される前に一度初期化されます。
OpenMP仕様 (セクション2.14.2)は、実際にはthreadprivate
ディレクティブの非常に優れた説明(およびより詳細な説明)を提供します。
threadprivate
変数の各コピーは、プログラムで指定された方法で1回初期化されますが、そのコピーへの最初の参照の前のプログラム内の指定されていないポイントで初期化されます。threadprivate
変数のすべてのコピーのストレージは、静的変数が基本言語でどのように処理されるかに従って解放されますが、プログラムの指定されていない時点で解放されます。スレッドが別のスレッドの
threadprivate
変数のコピーを参照するプログラムは不適合です。
threadprivate
変数の内容は、実行中のスレッドが変数を変更する別のタスクに切り替えた場合、タスクのスケジューリングポイント全体で変更される可能性があります。タスクのスケジューリングの詳細については、14ページのセクション1.3および113ページのセクション2.11を参照してください。
parallel
リージョンでは、マスタースレッドによる参照は、parallel
リージョンに遭遇したスレッド内の変数のコピーになります。シーケンシャルパーツでは、変数の最初のスレッドのコピーが参照されます。
threadprivate
変数の初期スレッドのコピー内のデータの値は、プログラム内の変数への2つの連続する参照間で存続することが保証されています。非初期スレッドの
threadprivate
変数のデータ値は、次のすべての条件が当てはまる場合にのみ、2つの連続するアクティブなparallel
領域間で存続することが保証されます。
どちらの
parallel
リージョンも、別の明示的なparallel
リージョン内にネストされていません。両方の
parallel
リージョンを実行するために使用されるスレッドの数は同じです。両方の
parallel
リージョンを実行するために使用されるスレッドアフィニティポリシーは同じです。囲んでいるタスク領域のdyn-var内部制御変数の値は、両方の
parallel
領域へのエントリでfalseです。これらの条件がすべて当てはまり、両方のリージョンで
threadprivate
変数が参照されている場合、それぞれのリージョンで同じスレッド番号を持つスレッドは、その変数の同じコピーを参照します。