用于因变量的 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 在评论中指出的那样,qxmij 需要线程私有:

!$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(共享)。