ワークシェアリング宣言子を並列で実行する場合、並列領域内でワークシェアリング構造を動的に囲む必要があります。新規のスレッドは起動されません。また、ワークシェアリング構造に入る時点で暗黙的なバリアはありません。
ワークシェアリング構造は、次のとおりです。
これらの宣言子についての詳細は、「OpenMP* Fortran Compiler Directives」(英語) を参照してください。
DO 宣言子は、DO ループ直後の繰り返しがスレッドのチームに振り分けられるようにし、それぞれの繰り返しが 1 つのスレッドにより実行されるようにします。DO 宣言子に続くループには、ループ制御が実行されない DO WHILE または DO ループは使用できません。DO ループの繰り返しは、既存のスレッドチーム間で振り分けられます。
DO 宣言子は、オプションで次のことが可能です。
データスコープ属性の制御
SCHEDULE 節を使用して、スケジュールの型とチャンクサイズを指定 (「スケジュールの型とチャンクサイズの設定」を参照してください)。
DO 宣言子の節では、次を指定します。
変数が PRIVATE、FIRSTPRIVATE、LASTPRIVATE、または REDUCTION かどうか。
ループの繰り返しがスレッドに scheduled される方法。
また、ORDERED 宣言子が DO 宣言子の動的範囲にある場合は ORDERED 節を指定する必要があります。
オプションの NOWAIT 節を END DO 宣言子で指定しない場合は、スレッドは END DO 宣言子で同期します。NOWAIT を指定する場合、スレッドは同期化せず、先に完了したスレッドは、END DO 宣言子の次の命令に直接進みます。
GOTO 文または他の文を使用して、DO 構造の内部または外部に制御を移すことはできません。
オプションの END DO 宣言子を指定する場合、DO ループの最後のすぐ後に指定しなければなりません。END DO 宣言子を指定しない場合は、END DO 宣言子は DO ループの最後にあると仮定され、スレッドはその時点で同期します。
ループ変数は、デフォルトではプライベートであるため、明示的に宣言する必要はありません。
非反復的なワークシェアリング SECTIONS 宣言子を使用して、囲まれたコードのセクションをチーム内で分割します。各セクションは、1 つのスレッドによって 1 回だけ実行されます。
SECTION 宣言子がオプションである最初のセクションを除き、各セクションは、SECTION 宣言子から開始されます。SECTION 宣言子は、SECTIONS 宣言子と END SECTIONS 宣言子の記述範囲内になければなりません。
最後のセクションは、END SECTIONS 宣言子で終わります。NOWAIT を指定しない限り、スレッドがセクションを終了し、振り分けられていないセクションがなければ、スレッドは END SECTION 宣言子で待機します。
SECTIONS 宣言子には、変数に PRIVATE、FIRSTPRIVATE、LASTPRIVATE、または REDUCTION を指定した節をカンマ区切りのリストで指定できます。
次の例では、SECTIONS 宣言子と SECTION 宣言子を使用して、X_AXIS、Y_AXIS、Z_AXIS サブルーチンを並列に実行する方法を示します。最初の SECTIONS 宣言子はオプションです。
例 |
---|
!$OMP PARALLEL !$OMP SECTIONS !$OMP SECTION CALL X_AXIS !$OMP SECTION CALL Y_AXIS !$OMP SECTION CALL Z_AXIS !$OMP END SECTIONS !$OMP END PARALLEL |
囲まれたコードのブロックを、チームの 1 つのスレッドにのみ実行させる場合は、SINGLE 宣言子と END SINGLE 宣言子を使用します。
SINGLE 構造を実行していないスレッドは、NOWAIT を指定しない限り、END SINGLE 宣言子で待機します。
SINGLE 宣言子には、変数に PRIVATE または FIRSTPRIVATE を指定した節をカンマ区切りのリストで指定できます。
END SINGLE 宣言子が検出されると、暗黙的なバリアができ、スレッドはすべてのスレッドが完了するまで待機します。これは、NOWAIT オプションを使用して無効にできます。
次の例では、SINGLE 宣言子を最初に検出したスレッドが、OUTPUT と INPUT サブルーチンを実行します。
例 |
---|
!$OMP PARALLEL DEFAULT(SHARED) CALL WORK(X) !$OMP BARRIER !$OMP SINGLE CALL OUTPUT(X) CALL INPUT(Y) !$OMP END SINGLE CALL WORK(Y) !$OMP END PARALLEL |