为什么Fortran中的以下代码仅在我将循环变量放入' i'和' j'作为子程序的输入参数' mat_init&#39 ;?循环变量' i'和' j'被声明为私有,所以在我调用它时它们是否应该在子例程中保持私有状态?
program main
use omp_lib
implicit none
real(8), dimension(:,:), allocatable:: A
integer:: i, j, n
n = 20
allocate(A(n,n)); A(:,:) = 0.0d+00
!$omp parallel do private(i, j)
do i=1,n
do j=1,n
call mat_init
end do
end do
do i=1,n
write(*,'(20f7.4)') (A(i,j), j=1,n)
end do
contains
subroutine mat_init
A(i,j) = 1.0d+00
end subroutine
end program main
我知道这与“词汇”有关。和'动态'延伸,但我不明白为什么OpenMP以这种方式实现,以便不识别“dymanic”中的私有变量'在平行区域内延伸。对我来说似乎不符合逻辑,或者我做错了什么?
答案 0 :(得分:0)
首先,我认为子例程mat_init应该明确地将i和j的值作为输入参数。然后,i和j的值必须是私有的,因为每个线程都对i和j的特定值起作用。我还认为openmp会认识到我是私有的,因为并行化循环位于i上。同上j。但是,这适用于全局变量i和j,而不适用于子例程内部的那些变量。因此,您必须指定i和j是私有的,以强制子例程内部变量体现这一方面。
我认为问题是由于子例程mat_init的重新进入。确实,当多个线程同时以不同的i和j值进入子例程时会发生什么?如果您不执行任何特殊操作,则被调用的子例程可能无法识别i和j的私有方面。
通常,不欢迎在循环内多次调用子例程,因为每次调用都需要一定的时间。我建议编写一个并行化的子例程,而不是在并行化的部分中调用该子例程。