OpenMP并行编程中的常见块问题 [英] Issue with common block in OpenMP parallel programming

查看:248
本文介绍了OpenMP并行编程中的常见块问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于在Fortran中的并行编程中使用通用块,我有几个问题。


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

  2. 他们如何传递信息?我想为每个线程分别设置公共时钟,并希望它们通过并行区域的末尾传递信息。这是否发生在这里? c> Condact 子例程再次覆盖它们,但函数使用 Condact 子例程中的值。做第二个子程序和函数为每个线程复制前一个子程序的变量?

     程序
    ...
    !循环,我想并行
    !$ OMP并行DO
    !我需要删除所有常见的块和threadprivate它们在这里吗?
    I = 1,N
    ...
    调用FORD(i,j)
    ...
    !$ OMP END并行DO
    结束程序

    子程序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 /)
    !此子程序重写b1,c1和f1变量的值。
    CALL CONDACT(genflg,lapflg)
    返回
    结束子程序

    子程序(genflg,lapflg)
    common / ellip / b1,c1,f1 ,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2
    !$ OMP threadprivate(/ ellip /)
    !这个子程序再次改写b1,c1和f1
    调用函数f(x)
    RETURN
    END

    函数f(x)
    common / elliptical / b1,c1,f1,g1,h1,d1,
    。 b2,c2,f2,g2,h2,p2,q2,r2,d2
    !$ OMP threadprivate(/ ellip /)
    !这里该函数使用来自CONDAT子程序的b1,c1,f1的值。
    end



解决方案

首先如上面的注释所示,我强烈建议不要使用 common ,特别是在现代代码中,混合全局数据和并行性只是要求痛苦的世界 - 事实上,全球数据只是一个坏主意而已。



好的,您的问题:



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


不, threadprivate 是一个声明性指令,应该只用在声明部分的代码中,并且它必须出现在每个声明之后。



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


当你怀疑每个线程都会得到它自己版本的 common 块。当您输入第一个并行区域时,块中的值将是未定义的,除非您使用 copyin 从主线程广播值。对于随后的并行区域,只要每个区域中使用的线程数相同,值就会保留。



  1. 在区域之间,公共块中的值将为主线程中的值。这些通用块是通过子程序访问的吗?我的福特子程序重写通用块中的一些变量,Condat
    子程序再次重写它们,但函数使用Condat子程序中的
    值。是否可以重写并在这里使用threadprivate传递公共
    块变量?


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


I have a few questions about using common blocks in parallel programming in Fortran.

  1. My subroutines have common blocks. Do I have to declare all the common blocks and threadprivate in the parallel do region?

  2. How do they pass information? I want seperate common clock for each thread and want them to pass information through the end of parallel region. Does it happen here?

  3. My Ford subroutine changes some variables in common blocks and Condact subroutine overwrites over them again but the function uses the values from Condact subroutine. Do the second subroutine and function copy the variables from the previous subroutine for each thread?

    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
    

解决方案

Firstly as the comment above says I would strongly advise against the use of common especially in modern code, and mixing global data and parallelism is just asking for a world of pain - in fact global data is just a bad idea full stop.

OK, your questions:

  1. My subroutines has common blocks. Do I have to declare all the common block and threadprivate in the parallel do region?

No,threadprivate is a declarative directive, and should be used only in the declarative part of the code, and it must appear after every declaration.

  1. How do they pass information? I want seperate common clock for each thread and want them to pass information through the end of parallel region. Does it happen here?

As you suspect each thread will gets its own version of the common block. When you enter the first parallel region the values in the block will be undefined, unless you use copyin to broadcast the values from the master thread. For subsequent parallel regions the values will be retained as long as the number of threads used in each region is the same. Between regions the values in the common block will be those of the master thread.

  1. Are those common block accessible through the subroutine? My Ford subroutine rewrite some variables in common block and Condat subroutine rewrite over them again but the function uses the values from Condat subroutine. Is that possible rewrite and pass the common block variable using threadprivate here?

I have to admit I am unsure what you are asking here. But if you are asking whether common can be used to communicate variables between different sub-programs in OpenMP code, the answer is yes, just as in serial Fortran (note capitalisation)

这篇关于OpenMP并行编程中的常见块问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆