OpenMP 並列コンパイラ指示文:DO ループの直後の繰り返しを並列実行しなくてはならないことを指定します。
形式
c$OMP DO [clause[[,] clause] ... ]
c
次のいずれか:C (または c),!,* (「並列指示文の構文規則」を参照)
clause
以下のいずれか。
ORDERED
DO 指示文の動的寸法に順序付きセクションが含まれている場合には指定しなくてはなりません。順序付きセクションの詳細については,「ORDERED」を参照してください。
SCHEDULE (type[, chunk])
DO ループの繰り返しを,チームのスレッド間でどのように分割するかを指定します。chunk はスカラ整数式でなくてはなりません。以下の 4 つの type を使用することができ,そのうちの 3 つではオプション・パラメタの chunk を使用できます。
形式 | 効果 |
---|---|
STATIC | 繰り返しの回数をチーム内のスレッドの数で割り,繰り返しを連続した複数の部分に分割します。その後,各部分は,ループの実行が開始される前にそれぞれのスレッドに送られます。
chunk が指定されている場合,繰り返しは chunk で指定された大きさの部分に分割されます。これらの部分は,チーム内のスレッドに,スレッド番号のラウンドロビン方式で静的に送られます。 |
DYNAMIC | 繰り返しの組を動的に取得することができます。chunk が指定されていない場合の基本値は 1 です。
chunk が指定されている場合,繰り返しは chunk で指定された大きさの部分に分割されます。個々のスレッドは,1 つの繰り返しの部分を終了した時点で,次の繰り返しの組を動的に取得します。 |
GUIDED | 繰り返しの数の最小値を指定することができます。chunk が指定されていない場合の基本値は 1 です。
chunk が指定されている場合,チャンクの大きさは,送付に成功するたびに指数関数的に減らされていきます。chunk は,1 回で送付される繰り返しの数の最小値を指定します。chunk 個未満の繰り返ししか残っていなければ,残りのすべての繰り返しが送付されます。 |
RUNTIME 1 | 実行時までスケジューリングの決定を据え置きます。環境変数 OMP_SCHEDULE を使うと,実行時にスケジュールの形式とチャンクの大きさを選択することができます。 |
1 この形式では chunk は使用できません。 |
SCHEDULE 節が使用されなかった場合の基本スケジュール形式は STATIC です。
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 ループ内のブロック単位の言語要素です。ループ制御変数が並列 DO の LASTPRIVATE 並びにも含まれている場合,その変数は外側の 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