这是我第一次使用OpenMP,我将它应用于Fortran。我碰巧在调整循环时出现问题,其中存在需要从其先前值更新的变量。我尝试使用PRIVATE
子句,但结果远不是串行计算(没有OpenMP)的结果。
我在OpenMP website找了一个地方,我找到了一个使用!$OMP PARALLEL DO ORDERED
的解决方案,最终有效(与序列产生相同的结果)。但似乎通过使用它,计算速度比仅使用PRIVATE
子句慢得多。
有没有其他方法可以在一个案例中应用OpenMP以获得最大速度?
使用ORDERED
选项的代码。
!$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
代码仅使用PRIVATE
子句
!$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
答案 0 :(得分:1)
正如弗朗索瓦在评论中指出的那样,qx
和mij
需要线程私密:
!$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
不需要是私有的,因为只能通过索引i
访问它。所以所有线程都访问它的不同部分。但是,如果您之后需要访问元素,请确保它是公共的(共享)。