Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parallel processing OpenMP并行编程中的公共块问题_Parallel Processing_Fortran_Openmp_Fortran Common Block - Fatal编程技术网

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

Parallel processing OpenMP并行编程中的公共块问题,parallel-processing,fortran,openmp,fortran-common-block,Parallel Processing,Fortran,Openmp,Fortran Common Block,我有几个关于在Fortran并行编程中使用公共块的问题 我的子程序有公共块。我必须声明并行Do区域中的所有公共块和threadprivate吗 他们如何传递信息?我希望每个线程有单独的公共时钟,并希望它们通过并行区域的末尾传递信息。是在这里发生的吗 MyFord子例程更改公共块中的一些变量,并且Condact子例程再次覆盖它们,但函数使用Condact子例程中的值。第二个子例程和函数是否为每个线程复制前一个子例程中的变量 program ... ! Loop which I want to pa

我有几个关于在Fortran并行编程中使用公共块的问题

  • 我的子程序有公共块。我必须声明并行Do区域中的所有公共块和threadprivate吗

  • 他们如何传递信息?我希望每个线程有单独的公共时钟,并希望它们通过并行区域的末尾传递信息。是在这里发生的吗

  • My
    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
    

  • 首先,正如上面的评论所说,我强烈建议不要使用
    common
    ,尤其是在现代代码中,而将全局数据和并行性混合在一起只会带来一个痛苦的世界——事实上,全局数据只是一个坏主意

    好,你的问题是:

  • 我的子程序有公共块。我必须申报所有的货物吗 并行do区域中的common block和threadprivate
  • 否,
    threadprivate
    是一个声明性指令,只能在代码的声明性部分使用,并且必须出现在每个声明之后

  • 他们如何传递信息?我想为每一个单独的普通时钟 线程并希望它们通过并行的末尾传递信息 区域是在这里发生的吗
  • 正如您所怀疑的,每个线程都将获得其自己版本的
    common
    块。当您进入第一个并行区域时,块中的值将是未定义的,除非您使用
    copyin
    从主线程广播值。对于后续并行区域,只要每个区域中使用的线程数相同,这些值就会保留。在区域之间,公共块中的值将是主线程的值

  • 这些公共块是否可以通过子例程访问?我的福特子程序重写了公共块和Condat中的一些变量 子例程再次重写它们,但函数使用这些值 从Condat子程序。这是否可能重写并传递公共消息 在这里使用threadprivate阻止变量

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

    如何将common块转换为模块

    common/root/root1、root2
    更改为
    use gammax
    ,然后创建一个包含以下内容的新文件
    root.f

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

    全局数据和并行化通常是个坏主意。使用公共块是一个更糟糕的想法。这是一个旧代码,还是你写了一些新的?您肯定应该首先尝试去除代码中的公共块。另一个问题是,您在公共块中有什么样的数据。是为每个(i,j)定义并在每次调用时重用的东西吗?或者它是包含所有(i,j)的结果的东西?@haraldkl,我正在尝试使用openmp并行化一个非常旧的代码,其中充满了公共块!(我知道我可以使用module,但我想尝试使用common block和threadprivate 1st)@haraldkl,每次调用时都会覆盖common block变量。它们只是在子程序中的计算过程中保存一些数据。这就是你想知道的吗?我真的很抱歉,但在你的另一个问题中,你问了如何摆脱这些常见的障碍,这真的是一条路要走。信不信由你,花点力气摆脱它们,会帮你省去很多痛苦。@lanBush谢谢你,answar。第三个问题:b1=2在主程序中,在福特子程序中,它覆盖了b1=4,因此Condact子程序和函数f(x)将看到b1=4。是吗?是的,这是普通块的替代品。但类似的问题仍然存在。