Fortran 两个openmp有序块,没有结果并行化
我正在写一个Fortran程序,需要有可复制的结果(用于出版)。我对以下代码的理解是,它应该是可复制的Fortran 两个openmp有序块,没有结果并行化,fortran,openmp,Fortran,Openmp,我正在写一个Fortran程序,需要有可复制的结果(用于出版)。我对以下代码的理解是,它应该是可复制的 program main implicit none real(8) :: ybest,xbest,x,y integer :: i ybest = huge(0d0) !$omp parallel do ordered private(x,y) shared(ybest,xbest) schedule(static,1) do i = 1,10 !$omp ordered
program main
implicit none
real(8) :: ybest,xbest,x,y
integer :: i
ybest = huge(0d0)
!$omp parallel do ordered private(x,y) shared(ybest,xbest) schedule(static,1)
do i = 1,10
!$omp ordered
!$omp critical
call random_number(x)
!$omp end critical
!$omp end ordered
! Do a lot of work
call sleep(1)
y = -1d0
!$omp ordered
!$omp critical
if (y<ybest) then
ybest = y
xbest = x
end if
!$omp end critical
!$omp end ordered
end do
!$omp end parallel do
end program
代码按如下方式运行:
real 0m10.047s
user 0m0.003s
sys 0m0.003s
real 0m10.037s
user 0m0.003s
sys 0m0.004s
但是,如果注释掉已排序的块,它将按以下时间运行:
real 0m10.044s
user 0m0.002s
sys 0m0.003s
real 0m3.021s
user 0m0.002s
sys 0m0.004s
- 编辑-
real(8) function f(x)
implicit none
real(8), intent(in) :: x
! local
real(8) :: tmp
integer :: i
tmp = 0d0
do i = 1,10000000
tmp = tmp + cos(sin(x))/real(i,8)
end do
f = tmp
end function
real 0m2.229s --- no openmp
real 0m2.251s --- with openmp and ordered
real 0m0.773s --- with openmp but ordered commented out
此程序不符合OpenMP标准。具体来说,问题是您有多个
有序的区域,循环的每次迭代都将执行这两个区域。OpenMP 4.0标准有这样的表述(2.12.8,限制,第16行,第139页):
在执行循环迭代或循环区域内的循环嵌套期间,线程不得执行多个绑定到同一循环的有序区域
地区
如果有多个
有序的
区域,则必须具有条件代码路径,以便在任何循环迭代中只能执行其中一个路径
还值得注意的是,您所订购区域的位置似乎对性能有影响。使用gfortran 5.2进行测试时,在每个循环迭代中按顺序执行有序区域后,所有内容都会显示出来,因此在循环开始时使用有序块会导致串行性能,而在循环结束时使用有序块则不会产生这种影响,因为在块并行化之前的代码。使用ifort 15进行测试并没有那么引人注目,但我仍然建议您对代码进行结构化,使您的有序块出现在任何代码之后,而不是需要在循环迭代中进行并行化 如何设置线程数?你的OMP\u线程数是多少?您如何确定它不是并行运行的?性能度量的结果到底是什么样的?循环是并行运行的,这意味着100次迭代在线程之间共享。每个线程只在自己的数据上运行f,除非f中还有$omp。这就是数据的并行性。我想这就是你的意思。现在你的问题是什么?Vladmir,我使用环境变量OMP_NUM_THREADS,对于linux等于6,对于max等于4。
top
显示它以100%的速度运行,有时甚至有一点超过。innoSPG,f中有一个OMP pragma,有点像。我必须通过声明一些模块变量私有$omp线程专用
。我不知道你所说的“数据并行性”是什么意思。我希望每个线程对不同的x
值执行f
。也许我还应该说,在不担心再现性的代码中(因此缺少有序结构),top
显示大约400%或600%。非常感谢!将代码重新构造为只有一个有序部分后,使用单有序构造的时间为1.056,不使用单有序构造的时间为3.240。
real(8) function f(x)
implicit none
real(8), intent(in) :: x
! local
real(8) :: tmp
integer :: i
tmp = 0d0
do i = 1,10000000
tmp = tmp + cos(sin(x))/real(i,8)
end do
f = tmp
end function
real 0m2.229s --- no openmp
real 0m2.251s --- with openmp and ordered
real 0m0.773s --- with openmp but ordered commented out