用于因变量的 OpenMP
OpenMP for dependent variables
第一次使用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
正如 Francois 在评论中指出的那样,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
访问它。所以所有线程都访问它的不同部分。但是,如果之后需要访问这些元素,请确保它是 public(共享)。
第一次使用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
正如 Francois 在评论中指出的那样,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
访问它。所以所有线程都访问它的不同部分。但是,如果之后需要访问这些元素,请确保它是 public(共享)。