Sun Studio 12: Fortran プログラミングガイド

10.3.1.3 明示的並列化の抑制

一般に、ユーザーがコンパイラにループを並列化するように明示的に指示している場合、コンパイラはそのようにします。ただし、例外もあり、ループによってはコンパイラが並列化を行わないものがあります。

次に、DO ループの明示的な並列化を妨げる抑制の中で、検出可能なものを示します。

-vpara および -loopinfo を指定してコンパイルすると、コンパイラが明示的にループを並列化している最中に問題を検出すると診断メッセージが発せられます。

次に、一般にコンパイラにより検出される並列化の問題を示します。

表 10–3 明示的な並列化時の問題

問題 

並列化されます 

警告メッセージ 

ループは、並列化されている別のループ内に入れ子にされています。 

いいえ 

いいえ 

ループは、並列化されたループの本文内で呼び出されているサブルーチン内にあります。 

いいえ 

いいえ 

フロー制御文で、ループから外部へのジャンプが許可されています。 

いいえ 

はい 

ループの添字変数が、悪影響を受けています。 

はい 

いいえ 

ループ内の変数に、ループ繰越の依存があります。 

はい 

はい 

ループ内の入出力文 — 通常、出力順序は予想できないので賢明な処理ではありません。

はい 

いいえ 

例: 入れ子にされたループ


      ...
!$OMP PARALLEL DO
      do 900 i = 1, 1000      !  並列化されます (外側のループ)
        do 200 j = 1, 1000    !  並列化されません。警告も発しません
            ...
200   continue
900      continue
      ...

例: サブルーチン内で並列化されたループ


 program main
      ...
!$OMP PARALLEL DO
      do 100 i = 1, 200      <- 並列化されます
        ...
        call calc (a, x)
        ...
100      continue
      ...
subroutine calc ( b, y )
      ...
!$OMP PARALLEL DO
      do 1 m = 1, 1000       <- 並列化されません
        ...
1      continue
      return
      end

この例では、サブルーチン自体が並列で実行されているので、その中のループは並列化されません。

例: ループから外部へのジャンプ


!$omp parallel do
      do i = 1, 1000     ! <- 並列化されず、エラーとなります
        ...
        if (a(i) .gt. min_threshold ) go to 20
        ...
      end do
20      continue
      ...

並列化のマークが付いたループの外にジャンプがあると、コンパイラはエラーと診断します。

例: ループ依存性を持つループの変数


demo% cat vpfn.f
      real function fn (n,x,y,z)
      real y(*),x(*),z(*)
      s = 0.0
!$omp parallel do private(i,s) shared(x,y,z)
      do  i = 1, n
          x(i) = s
          s = y(i)*z(i)
      enddo
      fn=x(10)
      return
      end
demo% f95 -c -vpara -loopinfo -openmp -O4 vpfn.f
"vpfn.f", line 5: Warning: the loop may have parallelization inhibiting reference
"vpfn.f", line 5: PARALLELIZED, user pragma used

ループは並列化されますが、可能なループ依存性は警告中で診断されます。しかし、ループ依存性のすべてがコンパイラによって診断できないことに注意してください。