web-dev-qa-db-ja.com

OpenMPthreadprivateとprivateの違い

OpenMPを使用してCプログラムを並列化しようとしています。

私はもっ​​と知りたいです:

  1. threadprivateディレクティブとprivate句の違いと
  2. その場合、それらのいずれかを使用する必要があります。

私の知る限り、違いはthreadprivateのグローバルスコープと、並列領域間で保持される値です。いくつかの例で、コードの一部に民営化する必要のあるグローバル/静的変数が含まれている場合、これらの変数はthreadprivateリストに含まれ、それらの初期値は-を使用してプライベートコピーにコピーされることがわかりました。 コピーイン

ただし、private句を使用してグローバル/静的変数を処理することを妨げるルールはありますか?おそらく実装の詳細はありますか?

OpenMP3.0仕様で説明が見つかりませんでした。

18
L30nardo SV.

あなたが覚えなければならない最も重要な違い:

  • 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変数が参照されている場合、それぞれのリージョンで同じスレッド番号を持つスレッドは、その変数の同じコピーを参照します。

21
Kyle_the_hacker