並列領域ディレクティブ

PARALLEL ディレクティブおよび END PARALLEL ディレクティブは、次のように並列領域を定義します:

!$OMP PARALLEL
!parallel region
!$OMP END PARALLEL

スレッドが並列領域を検出すると、スレッドのチームを形成して、そのスレッドがチームのマスタになります。チーム内のスレッド数は環境変数またはランタイム・ライブラリ・コール、あるいはその両方により制御することができます。

PARALLEL ディレクティブには、オプションで次のように指定した節をカンマ区切りのリストで指定できます。節には次のものが含まれます。

スレッド数の変更

一旦チームを形成すると、チーム内のスレッド数は並列領域では一定です。次の並列領域で使用されるスレッド数を明示的に変更するには、OMP_SET_NUM_THREADS ランタイム・ライブラリ・ルーチンをプログラムのシリアルな部分から呼び出します。このルーチンは、OMP_NUM_THREADS 環境変数で設定した値より優先されます。

例えば、OMP_NUM_THREADS 環境変数を使用してスレッド数を 6 に設定した場合、並列領域間のスレッド数は次のように変更できます。

   CALL OMP_SET_NUM_THREADS(3)
!$OMP PARALLEL
.
.
.
!$OMP END PARALLEL
CALL OMP_SET_NUM_THREADS(4)
!$OMP PARALLEL DO
.
.
.
!$OMP END PARALLEL DO

作業単位の設定

DO、SECTIONS、および SINGLE のようなワークシェアリング・ディレクティブを使用して、並列領域の文を作業単位に分割し、各単位が 1 つのスレッドにより実行されるように分配できます。

次の例では、!$OMP DO および !$OMP END DO ディレクティブと、これらのディレクティブに囲まれた文はすべて、並列領域の静的範囲を構成します。

!$OMP PARALLEL
!$OMP DO

DO I=1,N
B(I) = (A(I) + A(I-1))/ 2.0
END DO

!$OMP END DO
!$OMP END PARALLEL

次の例では、!$OMP DO および !$OMP END DO ディレクティブと、これらのディレクティブで囲まれた文 (WORK サブルーチンに含まれるすべての文を含む) はすべて、並列領域の動的範囲を構成します。

!$OMP PARALLEL DEFAULT(SHARED)
!$OMP DO

DO I=1,N
CALL WORK(I,N)
END DO

!$OMP END DO
!$OMP END PARALLEL

条件付き並列領域実行の設定

IF 節が PARALLEL ディレクティブに指定されていると、囲まれたコード領域は、スカラ論理式が .TRUE. に評価される場合にのみ並列で実行されます。それ以外の場合は、並列領域は順次実行されます。IF 節がない場合は、その領域はデフォルトで並列に実行されます。

次の例では、!$OMP DO および !$OMP END DO ディレクティブ内で囲まれた文は、4 つ以上のプロセッサが利用できる場合にのみ、並列で実行されます。それ以外の場合は、文は順次実行されます。

!$OMP PARALLEL IF (OMP_GET_NUM_PROCS() .GT.3)
!$OMP DO

DO I=1,N
Y(I) = SQRT(Z(I))
END DO

!$OMP END DO
!$OMP END PARALLEL

並列領域を実行中のスレッドが別の並列領域を検出すると、新しいチームを形成してそのチームのマスタになります。デフォルトでは、ネストされた並列領域は常に 1 つのスレッドで構成されるチームによって実行されます。


順次実行よりもパフォーマンスを向上させるには、並列領域に 1 つまたは複数のワークシェアリング構造を含めて、スレッドチームが並列で作業を実行できるようにする必要があります。ワークシェアリング構造を並列領域に含めることで、並列処理によるパフォーマンスの向上を得ることができます。