次の方法で共有


2.3 parallel コンストラクト

次のディレクティブは、並列領域を定義します。並列領域とは、複数のスレッドによって並列実行されるプログラムの領域のことです。 これは、並列実行を開始する基本的なコンストラクトです。

#pragma omp parallel [clause[ [, ]clause] ...] new-line
   structured-block

clause は次のいずれかになります。

if(scalar-expression)

private(variable-list)

firstprivate(variable-list)

default(shared | none)

shared(variable-list)

copyin(variable-list)

削減 (演算子変数リスト

num_threads(integer-expression)

スレッドが parallel コンストラクトを検出したときに、次のいずれかの条件に該当する場合、スレッドのチームが作成されます。

  • if 句が存在しない場合

  • if の式の評価結果が 0 以外の値になる場合

このスレッドが、スレッド番号 0 のチームのマスター スレッドになります。マスター スレッドを含むチーム内のすべてのスレッドがその領域を並列実行します。 if 式の値が 0 の場合、並列領域はシリアル化されます。

要求されるスレッド数を確認するために、次に示す規則が順に考慮されます。 条件が満たされた最初の規則が適用されます。

  1. num_threads 句が存在する場合、整数式の値が、要求されるスレッド数になります。

  2. omp_set_num_threads ライブラリ関数が呼び出されている場合、最も新しく実行された呼び出しでの引数値が、要求されるスレッド数になります。

  3. 環境変数 OMP_NUM_THREADS が定義されている場合、この関数変数の値が、要求されるスレッド数になります。

  4. 上記の方法がどれも使用されていなかった場合、要求されるスレッド数は実装で定義されます。

num_threads 句が存在する場合、この値が、その並列領域に対する omp_set_num_threads ライブラリ関数または OMP_NUM_THREADS 環境変数によって要求されるスレッド数よりも優先されます。 以降の並列領域については、この値の影響を受けません。

並列領域を実行するスレッド数は、スレッド数の動的な調整が有効になっているかどうかによっても異なります。 動的な調整が無効になっている場合、要求されるスレッド数によって並列領域が実行されます。 動的な調整が有効になっている場合、要求されるスレッド数が、並列領域を実行する最大スレッド数になります。

スレッド数の動的な調整が無効になっているときに並列領域が検出され、その並列領域に対して要求されるスレッド数が、ランタイム システムが提供できるスレッド数を超えている場合、プログラムの動作は実装によって定義されます。 たとえば、実装によって、プログラムの実行が中断されたり、並列領域がシリアル化されるなどします。

omp_set_dynamic ライブラリ関数と OMP_DYNAMIC 環境変数を、スレッド数の動的な調整を有効または無効にする目的で使用できます。

任意時にスレッドを実際にホストしている物理的なプロセッサの数は、実装で定義されます。 チームのスレッドはいったん作成されると、その並列領域の存続期間中、その数が維持されます。 この数は、別の並列領域に対しては、開発者によって明示的に、またはランタイム システムによって自動的に変更できます。

並列領域の動的範囲内に含まれるステートメントは各スレッドによって実行され、各スレッドは、他のスレッドとは異なるステートメントのパスを実行できます。 並列領域の構文範囲外で発生するディレクティブは、孤立したディレクティブと呼ばれます。

並列領域の終端には暗黙のバリアがあります。 チームのマスター スレッドのみが、並列領域の終端で実行を続行します。

並列領域を実行するチーム内の 1 つのスレッドが別の parallel コンストラクトを検出した場合、このスレッドが新しいチームを作成し、その新しいチームのマスター スレッドになります。 入れ子になった並列領域は、既定ではシリアル化されます。 結果、既定では、入れ子になった並列領域は、1 つのスレッドで構成されるチームによって実行されます。 この既定の動作は、ランタイム ライブラリ関数 omp_set_nested または環境変数 OMP_NESTED のいずれかを使用して変更できます。 ただし、入れ子になった並列領域を実行するチーム内のスレッド数は実装で定義されます。

parallel ディレクティブに対する制限は次のとおりです。

  • ディレクティブ内には最大で 1 つの if 句を含めることができます。

  • if 式または num_threads 式内に副作用が発生するかどうかについては未定義です。

  • 並列領域内部で throw を実行する場合、同じ構造化ブロックの動的範囲内で実行を再開させる必要があります。また、例外をスローした同じスレッドでキャッチする必要があります。

  • ディレクティブ内に含めることができる num_threads 句は 1 つだけです。 num_threads 式は、並列領域のコンテキスト外で評価されます。またこの式は、正の整数値に評価される必要があります。

  • if 句と num_threads 句の評価の順番は未定義です。

クロス リファレンス

  • privatefirstprivatedefaultsharedcopyinreduction の各句については、25 ページの「2.7.2 データ共有属性句」を参照してください。

  • OMP_NUM_THREADS 環境変数については、48 ページの「4.2 OMP_NUM_THREADS」を参照してください。

  • omp_set_dynamic ライブラリ関数については、39 ページの「3.1.7 omp_set_dynamic 関数」を参照してください。

  • OMP_DYNAMIC 環境変数については、49 ページの「4.3 OMP_DYNAMIC」を参照してください。

  • omp_set_nested 関数については、40 ページの「3.1.9 omp_set_nested 関数」を参照してください。

  • OMP_NESTED 環境変数については、49 ページの「4.4 OMP_NESTED」を参照してください。

  • omp_set_num_threads ライブラリ関数については、36 ページの「Section 3.1.1」を参照してください。