【问题标题】:OpenMP for dependent variables因变量的 OpenMP
【发布时间】:2015-08-05 22:12:58
【问题描述】:

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

【问题讨论】:

  • incre 应该是“public”,mij 应该是“private”。请在您的 !$OMP 语句中添加 DEFAULT(NONE) 以确保不要忘记变量的状态
  • 我忘记了 qx 是无用的(但私有的)。只有第二个版本可以加快你的代码。子句 ORDERED 仅用于调试目的...
  • 啊,我忘了把mij 私下,但非常感谢您指出将incre 公开。我只知道 ORDERED 子句仅用于调试。也许下次我应该仔细阅读其他代码。

标签: parallel-processing fortran openmp fortran90 gfortran


【解决方案1】:

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

【讨论】:

  • 所以我说在嵌套循环中是否正确,该进程将只划分到外部循环,以便通过外部循环索引访问的任何变量都不应该是私有的,即使它在循环中再次被访问?
  • 是的,只有紧跟 OpenMP 语句的 do 循环被并行化。如果我正确理解了您问题的第二部分,那么是的,每个线程都会对自己的一组私有变量执行内部循环。如果对共享变量/数组的访问不干扰其他线程,则无需将这些变量设为私有。
  • 太棒了。我现在对 OpenMP 有所了解。谢谢@alexander。
猜你喜欢
  • 2011-01-07
  • 2019-06-15
  • 2014-12-08
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多