Parallel processing 因变量的OpenMP

Parallel processing 因变量的OpenMP,parallel-processing,fortran,openmp,fortran90,gfortran,Parallel Processing,Fortran,Openmp,Fortran90,Gfortran,这是我第一次使用OpenMP,我将其应用于Fortran。我在调整循环时遇到了一个问题,其中有一个变量需要从其以前的值更新。我尝试使用PRIVATE子句,但结果与串行计算(没有OpenMP)的结果相差甚远 我查看了中的某个地方,发现了一个使用的解决方案$OMP并行DO排序,最终有效(产生与串行相同的结果)。但是,通过使用该子句,计算速度似乎比仅使用PRIVATE子句要慢得多 在这种情况下,是否有其他方法应用OpenMP以获得最大速度 使用有序选项进行编码 !$OMP PARALLEL DO OR

这是我第一次使用OpenMP,我将其应用于Fortran。我在调整循环时遇到了一个问题,其中有一个变量需要从其以前的值更新。我尝试使用
PRIVATE
子句,但结果与串行计算(没有OpenMP)的结果相差甚远

我查看了中的某个地方,发现了一个使用
的解决方案$OMP并行DO排序
,最终有效(产生与串行相同的结果)。但是,通过使用该子句,计算速度似乎比仅使用
PRIVATE
子句要慢得多

在这种情况下,是否有其他方法应用OpenMP以获得最大速度

使用
有序
选项进行编码

!$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

正如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
$OMP并行DO专用(i、j、value、beta、qx、mij)
i=ca,cb吗
增量(i)=0.0d0
值=17.0d0*li(i)
do j=cx,cy
qx=hi(i)-hj(j)
mij=dsqrt(qx)

如果(mij incre应该是“public”而mij应该是“private”。请在您的!$OMP语句中添加默认值(NONE),以确保不要忘记变量的状态。我忘记了qx,这是无用的(但私有的)。只有第二个版本可以加快您的代码速度。ORDERED子句仅用于调试目的…啊,我忘了将
mij
放在私下,但非常感谢您指出将
incr
放在公共场合。我只知道ORDERED子句仅用于调试。也许下次我应该仔细阅读其他代码。那么我的说法正确吗嵌套循环该进程将只划分到外循环,因此,通过外循环索引访问的任何变量都不应是私有的,即使之后在循环中再次访问该变量?是的,只有直接在OpenMP语句后面的
do
循环是并行的。如果我正确理解了问题的第二部分,则n是的,每个线程将在自己的私有变量集上执行内部循环。如果对共享变量/数组的访问不会干扰其他线程,则无需将这些变量设置为私有。太好了。我现在了解了OpenMP。谢谢@alexander。
!$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