Openmpループ並列化---ループネスト内部は並列化できません
10.3.1.3明示的並列化抑制要因
一般に、コンパイラにループの並列化を明示的に指導すると、コンパイラが実行されます.ただし、例外もあります.コンパイラによっては並列化されないループがあります.
以下は、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を実行する関数の呼び出しが含まれており、ランタイムエラーが発生します.