两个openmp有序块,没有产生并行化

时间:2015-08-18 15:06:13

标签: 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
    !$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

在我的情况下,有一个代替“睡眠”的功能需要很长时间才能计算,我希望它能并行完成。根据OpenMP标准,应该在这个例子中睡觉并行执行吗?我认为它应该是(基于此How does the omp ordered clause work?),但是使用gfortran 5.2.0(mac)和gfortran 5.1.0(linux)它并不是并行执行(至少,它没有加速) 。时间结果如下。

另外,我的猜测是关键陈述不是必要的,但我并不完全确定。

感谢。

- 编辑 -

在回应弗拉德米尔的评论时,我添加了一个完整的工作计划,其中包含时间结果。

#!/bin/bash
mpif90 main.f90
time ./a.out
mpif90 main.f90 -fopenmp
time ./a.out

代码以

运行
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
  • 编辑 -

作为对innoSPG的回应,以下是取代睡眠的非平凡功能的结果:

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

1 个答案:

答案 0 :(得分:1)

此程序不符合OpenMP标准。具体来说,问题是您有多个ordered区域,并且循环的每次迭代都将执行它们。 OpenMP 4.0标准就是这样说的(2.12.8,限制,第16行,第139页):

  

在循环区域内执行循环或循环嵌套的迭代期间,线程不得执行多个绑定到同一循环的有序区域   区域。

如果您有多个ordered区域,则必须具有条件代码路径,以便只能执行其中一个循环迭代。

值得注意的是,您所订购区域的位置似乎具有性能影响。使用gfortran 5.2进行测试后,为了进行每次循环迭代,在执行有序区域之后出现所有内容,因此在循环开始时使用有序块会导致串行性能,而在循环结束时使用有序块则没有这意味着块之前的代码是并行化的。使用ifort 15进行测试并不那么引人注目,但我仍然建议您构建代码,这样您的有序块就会出现在任何代码之后,而不是在循环迭代中而不是之前需要并行化。