OpenMP用于因变量

时间:2015-05-24 07:51:51

标签: parallel-processing fortran openmp fortran90 gfortran

这是我第一次使用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

1 个答案:

答案 0 :(得分:1)

正如弗朗索瓦在评论中指出的那样,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访问它。所以所有线程都访问它的不同部分。但是,如果您之后需要访问元素,请确保它是公共的(共享)。