OpenMP Fortran默认条款

Lin*_*g0k 1 fortran openmp

这种并行工作正常.

!$OMP PARALLEL Private(irep)
!$OMP DO
do irep = 1, nrep
  print *, "Using thread: ", omp_get_thread_num(), "irep: ", irep
end do
!$OMP END DO NOWAIT
!$OMP END PARALLEL
Run Code Online (Sandbox Code Playgroud)

这也很好.

!$OMP PARALLEL
!$OMP DO
do irep = 1, nrep
  print *, "Using thread: ", omp_get_thread_num(), "irep: ", irep
end do
!$OMP END DO NOWAIT
!$OMP END PARALLEL
Run Code Online (Sandbox Code Playgroud)

当我使用Default子句时,为什么它什么都不返回?

!$OMP PARALLEL DEFAULT(Private)
!$OMP DO
do irep = 1, nrep
  print *, "Using thread: ", omp_get_thread_num(), "irep: ", irep
end do
!$OMP END DO NOWAIT
!$OMP END PARALLEL
Run Code Online (Sandbox Code Playgroud)

非常感谢!

Jon*_*rsi 6

我们来看一个更简单的案例:

program testprivate
use omp_lib

integer :: nrep
nrep=16

!$OMP PARALLEL DEFAULT(Private)
print *, "Thread: ", omp_get_thread_num(), "sees nrep = ", nrep
!$OMP END PARALLEL

end program testprivate
Run Code Online (Sandbox Code Playgroud)

我们运行这个并得到:

$ gfortran -o private private.f90 -fopenmp
$ export OMP_NUM_THREADS=8
$ ./private
 Thread:            3 sees nrep =            0
 Thread:            0 sees nrep =            0
 Thread:            1 sees nrep =        32581
 Thread:            7 sees nrep =            0
 Thread:            4 sees nrep =            0
 Thread:            5 sees nrep =            0
 Thread:            2 sees nrep =            0
 Thread:            6 sees nrep =            0
Run Code Online (Sandbox Code Playgroud)

在进入私有部分时,OpenMP私有变量(无论是默认的还是其他私有变量)都是未定义的.这与循环索引irep无关,它在do循环中设置; 但是如果(比方说)你的编译器nrep在私有部分内将每个线程设置为零,那么循环将永远不会执行.更糟糕的是,每个线程可能有不同的nrep值,任何事情都可能发生.

所以你不想nrep成为private.你可能仍然拥有default(private) shared(nrep),甚至firstprivate(nrep),尽管这里没有任何优势让每个线程都有自己的优势nrep.