ワークシェアリング・ディレクティブを並列で実行する場合、並列領域内でワークシェアリング構造を動的に囲む必要があります。新規のスレッドは起動されません。また、ワークシェアリング構造に入る時点で暗黙的なバリアはありません。
ワークシェアリング構造は、次のとおりです。
DO および END DO ディレクティブ
SECTIONS、SECTION、および END SECTIONS ディレクティブ
SINGLE および END SINGLE ディレクティブ
DO ディレクティブは、DO ループ直後の繰返しがスレッドのチームに振り分けられるようにし、それぞれの繰返しが 1 つのスレッドにより実行されるようにします。DO ディレクティブに続くループには、ループ制御が実行されない DO WHILE または DO ループは使用できません。DO ループの繰返しは、既存のスレッドチーム間で振り分けられます。
DO ディレクティブは、オプションで次のことが可能です:
データスコープ属性の制御 (「データスコープの制御」を参照してください。)
SCHEDULE 節を使用して、スケジュールの型とチャンクサイズを指定 (「スケジュールの型とチャンクサイズの設定」を参照してください)。
DO ディレクティブの節では、次を指定します:
変数が PRIVATE、FIRSTPRIVATE、LASTPRIVATE、または REDUCTION かどうか。
ループの繰返しがスレッドにスケジュールされる方法。
また、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 サブルーチンを並列に実行する方法を示します。最初の SECTION ディレクティブはオプションです。
!$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 ディレクティブを使用します。
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