Parallel processing OpenMP并行区域内的顺序循环

Parallel processing OpenMP并行区域内的顺序循环,parallel-processing,fortran,openmp,intel-fortran,Parallel Processing,Fortran,Openmp,Intel Fortran,我有三个嵌套循环。我想将中间的循环并行化如下: do a = 1,amax !$omp parallel do private(c) do b = 1,bmax do c = 1,cmax call mysubroutine(b,c) end do end do !$omp end parallel do end do 然而,这会产生一个问题,因为对于循环的每次迭代,线程都会生成,在内部循环中运行,然后终止。我假设

我有三个嵌套循环。我想将中间的循环并行化如下:

  do a = 1,amax
    !$omp parallel do private(c)
    do b = 1,bmax
      do c = 1,cmax
        call mysubroutine(b,c)
      end do
    end do
    !$omp end parallel do
  end do
然而,这会产生一个问题,因为对于循环的每次迭代,线程都会生成,在内部循环中运行,然后终止。我假设这会导致过多的开销,因为内部循环执行~10^-4秒不会花费太长时间。所以我只想产生一次线程。在继续执行a循环的同时,如何在启动a循环之前生成线程?由于代码的性质,循环的每个迭代都必须完成,然后才能执行下一个循环。例如,这显然不起作用:

  !$omp parallel private(c)
  do a = 1,amax
    !$omp do 
    do b = 1,bmax
      do c = 1,cmax
        call mysubroutine(b,c)
      end do
    end do
    !$omp end do
  end do
  !$omp end parallel
因为所有线程都将尝试执行a循环。感谢您的帮助。

例如,这显然不起作用

这不仅不清楚,而且是完全错误的。你展示的代码正是你应该用privatea做得更好的地方

因为所有线程都将尝试执行a循环

他们当然会,而且必须这样做!如果他们要参与omp do内部循环中的工作共享,所有人都必须执行它!如果他们不执行它,他们就不会在那里帮助处理内部循环


另一句话:omp do嵌套循环的collapse2子句可能会使您受益。

断言这会导致过多开销的一个好方法是使用不同数量的线程来评估缩放


1s是一段很长的时间,重新绘制线程的成本并不高…

我的意思是说任何合理的OpenMP运行时都会维护一个线程池,因此重新生成线程的原始断言无论如何都是错误的!如果您对此有疑问,请查看LLVM或GCC OpenMP运行时的代码,或者在Linux上,查看strace,看看有多少克隆调用。谢谢,我似乎对OMP在并行环境中处理a循环的方式有误解。我的想法是,每个线程都会分别尝试执行a循环,也就是说,循环将被复制。显然情况并非如此。我仍然不明白这是如何处理的。我的想法是,迭代器应该是一个公共变量,而不是私有变量,因为我希望循环的处理与第一种情况完全相同,只是没有线程的过度重新启动。它们是单独执行的。但是你有omp-do内部来实际执行工作共享。