问题描述
这是我第一次使用OpenMP,并将其应用于Fortran。我遇到了调整循环的问题,其中有一个变量需要从其先前的值进行更新。我试过使用 PRIVATE
子句,但结果远不是由串行计算(没有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 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 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!