因变量的OpenMP [英] OpenMP for dependent variables

查看:167
本文介绍了因变量的OpenMP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我第一次使用OpenMP,并将其应用于Fortran。我遇到了调整循环的问题,其中有一个变量需要从其先前的值进行更新。我试过使用 PRIVATE 子句,但结果远不是由串行计算(没有OpenMP)导致的结果。



我在 OpenMP网站,我找到了一个使用!$ OMP PARALLEL DO ORDERED 的解决方案,它终于可以工作(与串口产生相同的结果)。但似乎通过使用它,计算速度比使用 PRIVATE 子句要慢很多。



是有没有其他的方法可以将OpenMP应用于案例中以获得最大速度?



使用 ORDERED 选项的代码。

 !$ OMP PARALLEL DO ORDERED PRIVATE(i,j)
do i = ca,cb
增加(i)= 0.0d0
值= 17.0d0 * li(i)
do j = cx,cy
qx = hi(i) - hj(j)
mij (i)* li(j)
!$ OMP ORDERED
增加(i)= dsqrt(qx)
if(mij <= value)then
beta = li如果
结束
结束
!$ $ OMP结束并行DO
结束c $ c>

仅使用 PRIVATE 子句的代码

 !$ OMP PARALLEL DO PRIVATE(i,j,incre,value,beta)
do i = ca,cb
incre(i)= 0.0d0
值= 17.0d0 * li(i)
do j = cx,cy
qx = hi(i) - hj(j)
mij = dsqrt(qx)
if(mij <= value)then
beta = li(i)* li(j)
incre(i)= incre(i)+ beta
end if
end do
end do
!$ OMP END PARALLEL DO


解决方案

正如Francois指出的他的评论 qx mij 需要是线程私有的:

 !$ OMP PARALLEL DO PRIVATE(i,j,value,beta,qx,mij)
do i = ca,cb
incre(i)= 0.0d0
值= 17.0d0 * li(i)
do j = cx,cy
qx = hi(i) - hj(j)
mij = dsqrt(qx) (b)如果(mij <=值)然后是
beta = li(i)* li(j)
incre(i)= incre(i)+ beta
如果
end do
end do
!$ OMP END PARALLEL DO

incre 不需要是私人的,因为对它的访问是打开的通过索引 i 。所以所有的线程访问它的不同部分。但是,如果您以后需要访问这些元素,请确保它是公共的(共享的)。

This is the first time I am using OpenMP, and I apply it for Fortran. I happened to have a problem adjusting the loop where there is a variable that requires update from its previous value. I tried using PRIVATE clause but the result is far from those resulted by serial computation (without OpenMP).

I looked somewhere in OpenMP website and I found one solution using !$OMP PARALLEL DO ORDERED which finally works (produce the same result with the serial one). But it seems that by using this, the speed of computation is considerably slower than using just PRIVATE clause.

Is there any other way to apply OpenMP in such as a case to get maximum speed?

Codes using ORDERED option.

!$OMP PARALLEL DO ORDERED PRIVATE(i,j)
do i = ca,cb
    incre(i) = 0.0d0
    value = 17.0d0*li(i)
    do j = cx,cy
        qx    = hi(i) - hj(j)
        mij   = dsqrt(qx)
        if( mij <= value ) then
            beta   = li(i)*li(j)
            !$OMP ORDERED
            incre(i) = incre(i) + beta
            !$OMP END ORDERED
        end if
    end do
end do
!$OMP END PARALLEL DO

Codes using only PRIVATE clause

!$OMP PARALLEL DO PRIVATE(i,j,incre,value,beta)
do i = ca,cb
    incre(i) = 0.0d0
    value = 17.0d0*li(i)
    do j = cx,cy
        qx    = hi(i) - hj(j)
        mij   = dsqrt(qx)
        if( mij <= value ) then
            beta   = li(i)*li(j)
            incre(i) = incre(i) + beta
        end if
    end do
end do
!$OMP END PARALLEL DO

解决方案

As Francois pointed out in his comments, qx and mij need to be thread private:

!$OMP PARALLEL DO PRIVATE(i,j,value,beta,qx,mij)
do i = ca,cb
    incre(i) = 0.0d0
    value = 17.0d0*li(i)
    do j = cx,cy
        qx    = hi(i) - hj(j)
        mij   = dsqrt(qx)
        if( mij <= value ) then
            beta   = li(i)*li(j)
            incre(i) = incre(i) + beta
        end if
    end do
end do
!$OMP END PARALLEL DO

incre does not need to be private, since access to it is only via the index i. so all threads access a different portion of it. However, if you need to access the elements afterwards, make sure it is public (shared).

这篇关于因变量的OpenMP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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