Openmpループ並列化---ループネスト内部は並列化できません



10.3.1.3明示的並列化抑制要因


一般に、コンパイラにループの並列化を明示的に指導すると、コンパイラが実行されます.ただし、例外もあります.コンパイラによっては並列化されないループがあります.
以下は、DOサイクルの明示的並列化を防止するために検出可能な主な抑制要因である.
  • DOサイクルは、並列化された別のDOサイクル内にネストされる.この例外は、間接ネストにも適用されます.サブルーチン呼び出しを含むループを明示的に並列化する場合、コンパイラがサブルーチンのループを並列化するように要求しても、これらのループは実行時に並列に実行されません.
  • フロー制御文は、DOループからのジャンプを可能にする.
  • サイクルのインデックス変数は、例えば等価であるなどの副作用によって影響される.

  • -vparaと-loopinfoを使用してコンパイルすると、コンパイラが明示的な並列化サイクル中に問題を検出したかどうかを示す診断メッセージが得られます.
    次の表は、コンパイラが検出した典型的な並列化の問題を示しています.表10~3は、明示的な並列化の問題です.
    に質問
    並列化
    警告メッセージ
    ループは、並列化された別のループにネストされます. 
    いいえ
    いいえ
    ループは、パラレルループ内で呼び出されるサブルーチンにあります. 
    いいえ
    いいえ
    フロー制御文では、ループからジャンプできます. 
    いいえ
    はい
    ループのインデックス変数は副作用の影響を受けます. 
    はい
    いいえ
    サイクル内の変数は、サイクル携帯依存性を有する. 
    はい
    はい
    サイクルでI/O文を使用する-出力順序が予測できないため、通常は賢明ではありません.
    はい
    いいえ
    例:ネストされたループ:
          ...
    !$OMP PARALLEL DO
          do 900 i = 1, 1000      !  Parallelized (outer loop)
            do 200 j = 1, 1000    !  Not parallelized, no warning
                ...
    200   continue
    900      continue
          ...

    例:サブルーチンで並列化されたループ:
     program main
          ...
    !$OMP PARALLEL DO
          do 100 i = 1, 200      <-parallelized
            ...
            call calc (a, x)
            ...
    100      continue
          ...
    subroutine calc ( b, y )
          ...
    !$OMP PARALLEL DO
          do 1 m = 1, 1000       <-not parallelized
            ...
    1      continue
          return
          end

    この例では、サブルーチン自体が並列に実行されるため、サブルーチンのループは並列化されない.
    例:ループからジャンプ:
    !$omp parallel do
          do i = 1, 1000     ! <- Not parallelized, error issued
            ...
            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

    ここで,ループは並列化されるが,警告では可能なループ携帯依存性が診断される.ただし、コンパイラはすべてのループ依存性を診断することはできません.

    10.3.1.4明示的並列化時のI/O


    以下の場合、パラレル実行のサイクルでI/Oを実行できます.
  • は、異なるスレッドからの出力が互いにインタリーブされている(プログラム出力が非確定である)点は重要ではない.
  • は、並列実行サイクルのセキュリティを確保することができる.

  • 例:ループにI/O文がある
    !$OMP PARALLEL DO PRIVATE(k)
          do i = 1, 10     !  Parallelized
            k = i
            call show ( k )
          end do
          end
          subroutine show( j )
          write(6,1) j
    1      format(’Line number ’, i3, ’.’)
          end
    demo% f95 -openmp t13.f
    demo% setenv PARALLEL 4
    demo% a.out
    
    Line number 9.
    Line number 4.
    Line number 5.
    Line number 6.
    Line number 1.
    Line number 2.
    Line number 3.
    Line number 7.
    Line number 8.

    ただし、再帰的なI/O、すなわちI/O文には、自身がI/Oを実行する関数の呼び出しが含まれており、ランタイムエラーが発生します.