Parallel processing 因变量的OpenMP
这是我第一次使用OpenMP,我将其应用于Fortran。我在调整循环时遇到了一个问题,其中有一个变量需要从其以前的值更新。我尝试使用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
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