DO 指示文 (TU*X のみ)

OpenMP 並列コンパイラ指示文DO ループの直後の繰り返しを並列実行しなくてはならないことを指定します。

形式

c$OMP DO [clause[[,] clause] ... ]

do_loop
[c$OMP END DO [NOWAIT]]

c
次のいずれか:C (または c),!* (「並列指示文の構文規則」を参照)

clause
以下のいずれか。

do_loop
DO の繰り返し (DO ループ)。DO WHILE や,ループ制御を持たない DO ループであってはなりません。DO ループの繰り返し変数は整数型でなくてはなりません。

DO ループの繰り返しは,既存のスレッドのチーム内で分散されます。DO 指示文に結合された DO ループのループ制御パラメタ値は,チーム内のすべてのスレッドで同じでなくてはなりません。

DO 指示文に結合された DO ループの外に飛越しすることはできません。

規則と振る舞い

END DO 指示文を使用する場合,この指示文はループの終わりの直後に置かなくてはなりません。END DO 指示文を指定しなければ,DO ループの終わりに END DO 指示文があるものと見なされます。

END DO 指示文で NOWAIT を指定すると,スレッドは並列ループの終わりで同期されません。先に終了したスレッドは,チームの他のメンバが DO 指示文を終了するのを待つことなく,ループの次の命令に進みます。

並列 DO ループの制御変数は,DO ループ内のブロック単位の言語要素です。ループ制御変数が並列 DOLASTPRIVATE 並びにも含まれている場合,その変数は外側の PARALLEL 領域中の同じ名前の変数にコピーされます。外側の PARALLEL 領域中の変数は,DO 指示文の LASTPRIVATE 並びで指定されている場合,SHARED でなくてはなりません。

DO 指示文では,SCHEDULE 節と ORDERED 節は 1 つしか指定できません。

DO 指示文は,チーム内のすべてのスレッドが遭遇するか,どのスレッドも遭遇しないように置かれていなくてはなりません。また,チーム内のすべてのスレッドが同じ順序で遭遇するようになっている必要があります。

関連情報

Compaq Fortran 並列コンパイラ指示文OpenMP Fortran API コンパイラ指示文Tru64 UNIX システム用の並列指示文

次の例では,ループ繰り返し変数は基本設定として非公開になっており,これを明示的に宣言する必要はありません。END DO 指示文は省略可能です。

	c$OMP PARALLEL
	c$OMP DO
	      DO I=1,N
	        B(I) = (A(I) + A(I-1)) / 2.0
	      END DO
	c$OMP END DO
	c$OMP END PARALLEL

並列領域中に複数の独立したループが存在する場合,次のように NOWAIT キーワードを使って,DO 指示文の終わりの暗黙の BARRIER を避けることができます。

	c$OMP PARALLEL
	c$OMP DO
	      DO I=2,N
	        B(I) = (A(I) + A(I-1)) / 2.0
	      END DO
	c$OMP END DO NOWAIT

	c$OMP DO
	      DO I=1,M
	        Y(I) = SQRT(Z(I))
	      END DO
	c$OMP END DO NOWAIT
	c$OMP END PARALLEL

正しい実行結果が,ループの最後の繰り返しが変数に代入する値に依存することがあります。このようなプログラムは,このような変数すべてを LASTPRIVATE 節への引数として並べなくてはなりません。これにより,変数の値は,ループが逐次的に実行された場合と同じ値になります。次に例を示します。

	c$OMP PARALLEL
	c$OMP DO LASTPRIVATE(I)
	      DO I=1,N
	        A(I) = B(I) + C(I)
	      END DO
	c$OMP END PARALLEL
	      CALL REVERSE(I)

この例では,並列領域の終わりでの I の値は,逐次的に実行した場合と同じ N+1 となります。

順序付きセクションは,並列に実行される作業からの出力を逐次的に並べるのに便利です。再入可能な I/O ライブラリーが存在していれば,次のプログラムは指標を逐次的な順序で印字します。

	c$OMP DO ORDERED SCHEDULE(DYNAMIC)
	      DO I=LB,UB,ST
	        CALL WORK(I)
	      END DO
	      ...
	      SUBROUTINE WORK(K)
	c$OMP ORDERED
	      WRITE(*,*) K
	c$OMP END ORDERED