Fortran OpenMP中的全局变量

时间:2015-04-23 19:18:32

标签: fortran openmp

为什么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”中的私有变量'在平行区域内延伸。对我来说似乎不符合逻辑,或者我做错了什么?

1 个答案:

答案 0 :(得分:0)

首先,我认为子例程mat_init应该明确地将i和j的值作为输入参数。然后,i和j的值必须是私有的,因为每个线程都对i和j的特定值起作用。我还认为openmp会认识到我是私有的,因为并行化循环位于i上。同上j。但是,这适用于全局变量i和j,而不适用于子例程内部的那些变量。因此,您必须指定i和j是私有的,以强制子例程内部变量体现这一方面。

我认为问题是由于子例程mat_init的重新进入。确实,当多个线程同时以不同的i和j值进入子例程时会发生什么?如果您不执行任何特殊操作,则被调用的子例程可能无法识别i和j的私有方面。

通常,不欢迎在循环内多次调用子例程,因为每次调用都需要一定的时间。我建议编写一个并行化的子例程,而不是在并行化的部分中调用该子例程。