OpenMP并行编程中的公共块问题

时间:2015-09-07 22:02:18

标签: parallel-processing fortran openmp fortran-common-block

我有一些关于在Fortran中使用并行编程中的公共块的问题。

  1. 我的子程序有公共块。我是否必须声明并行do区域中的所有公共块和threadprivate?

  2. 他们如何传递信息?我想为每个线程分别使用公共时钟,并希望它们通过并行区域的末尾传递信息。它会在这里发生吗?

  3. 我的Ford子例程更改了公共块中的一些变量,Condact子例程再次覆盖它们,但该函数使用Condact子例程中的值。第二个子例程和函数是否复制了每个线程的前一个子例程中的变量?

    program
    ...
    ! Loop which I want to parallelize
    !$OMP parallel DO
    !do I need to declear all common block and threadprivate them here?
    I = 1, N
    ...
    call FORD(i,j)
    ...
    !$OMP END parallel DO
    end program
    
    subroutine FORD(i,j)
    dimension zl(3),zg(3)
    common /ellip/ b1,c1,f1,g1,h1,d1,
    .               b2,c2,f2,g2,h2,p2,q2,r2,d2
    common /root/ root1,root2
    !$OMP threadprivate (/ellip/,/root/)
    !this subroutine rewrite values of b1, c1 and f1 variable.
    CALL CONDACT(genflg,lapflg)
    return
    end subroutine
    
    SUBROUTINE CONDACT(genflg,lapflg)
    common /ellip/ b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2
    !$OMP threadprivate (/ellip/)
    ! this subroutine rewrite b1, c1 and f1 again
    call function f(x)
    RETURN
    END
    
    function f(x)
    common /ellip/ b1,c1,f1,g1,h1,d1,
    .               b2,c2,f2,g2,h2,p2,q2,r2,d2
    !$OMP threadprivate (/ellip/)
    ! here the function uses the value of b1, c1, f1 from CONDAT subroutine.
    end
    

2 个答案:

答案 0 :(得分:1)

首先,正如上面的评论所说,我强烈建议不要使用common,特别是在现代代码中,混合全局数据和并行性只是要求一个痛苦的世界 - 实际上全球数据只是一个坏事想法完全停止。

好的,你的问题:

  
      
  1. 我的子程序有常见的块。我必须申报所有的   并行do区域中的公共块和threadprivate?
  2.   

不,threadprivate是一个声明性指令,只能在代码的声明部分使用,并且必须在每次声明后出现。

  
      
  1. 他们如何传递信息?我想要每个人都有一个共同的时钟   线程并希望它们通过并行结束传递信息   区域。它会在这里发生吗?
  2.   

您怀疑每个线程都会获得自己的common块版本。当您进入第一个并行区域时,块中的值将是未定义的,除非您使用copyin来广播主线程中的值。对于后续并行区域,只要每个区域中使用的线程数相同,就会保留这些值。在区域之间,公共块中的值将是主线程的值。

  
      
  1. 是否可以通过子程序访问这些公共块?我的Ford子程序在common block和Condat中重写了一些变量   子程序再次重写它们,但函数使用这些值   来自Condat子程序。这可能是重写并传递共同点   在这里使用threadprivate阻塞变量?
  2.   

我不得不承认我不确定你在这里问的是什么。但是,如果您在询问OpenMP代码中是否可以使用common来传递不同子程序之间的变量,答案是肯定的,就像在串行Fortran中一样(注意大写)

答案 1 :(得分:0)

如何将公共块转换为模块?

common /root/ root1, root2更改为use gammax,然后制作包含以下内容的新文件root.f

module root
implicit none
save
real :: root1, root2
!$omp threadprivate( root1, root2 )
end module root