OpenMP を使用して Fortran90 でプログラムを並列化しようとすると、セグメンテーション違反エラーが発生します。
!$OMP PARALLEL DO NUM_THREADS(4) &
!$OMP PRIVATE(numstrain, i)
do irep = 1, nrep
do i=1, 10
PRINT *, numstrain(i)
end do
end do
!$OMP END PARALLEL DO
「PRINT *、numstrain(i)」をコメントアウトするか、openmp フラグを削除すると、エラーなしで動作することがわかりました。numstrain(i) に並列アクセスするとメモリアクセス競合が発生するためだと思います。i と numstrain はプライベート変数として宣言済みです。誰かが私に理由を教えてもらえますか?どうもありがとう。:)
アップデート:
以前のバージョンを修正しましたが、このバージョンでは正しい結果を出力できます。
integer, allocatable :: numstrain(:)
integer :: allocate_status
integer :: n
!$OMP PARALLEL DO NUM_THREADS(4) &
!$OMP PRIVATE(numstrain, i)
n = 1000000
do irep = 1, nrep
allocate (numstrain(n), stat = allocate_status)
do i=1, 10
PRINT *, numstrain(i)
end do
deallocate (numstrain, stat = allocate_status)
end do
!$OMP END PARALLEL DO
ただし、このサブルーチンによって呼び出される別のサブルーチンにアクセスする numstrain を移動すると (コードは以下に添付)、1. 常に 1 つのスレッドで処理されます。2. ある時点 (i=4 または 5) で、Segmentation Fault:11 を返します。NUM_THREADS が異なると、Segmentation Fault:11 を返す変数 i が異なります。
integer, allocatable :: numstrain(:)
integer :: allocate_status
integer :: n
!$OMP PARALLEL DO NUM_THREADS(4) &
!$OMP PRIVATE(numstrain, i)
n = 1000000
do irep = 1, nrep
allocate (numstrain(n), stat = allocate_status)
call anotherSubroutine(numstrain)
deallocate (numstrain, stat = allocate_status)
end do
!$OMP END PARALLEL DO
subroutine anotherSubroutine(numstrain)
integer, allocatable :: numstrain(:)
do i=1, 10
PRINT *, numstrain(i)
end do
end subroutine anotherSubroutine
また、ヘルプ サブルーチンとメイン サブルーチンで割り当て/割り当て解除の両方を試み、ヘルプ サブルーチンでのみ割り当て/割り当て解除を試みました。何も変更されていません。