【问题标题】:Is it possible to "cross collapse" parallel loops?是否可以“交叉折叠”并行循环?
【发布时间】:2016-12-25 12:51:34
【问题描述】:

this answer 之后,我实际上有更复杂的代码,包含三个循环:

!$omp parallel 
!$omp do
do i=1,4 ! can be parallelized
  ...
  do k=1,1000 !to be executed sequentially
    ...
    do j=1,4  ! can be parallelized
    call job(i,j)

除了i=4,外层循环很快完成。所以我想在最里面的循环上启动线程,但在每个i-iteration 中按顺序保留k-loop。事实上,k 循环遍历随机数生成器的变化状态,因此无法并行化。

如何仅折叠 ij 循环?我怀疑ordered 子句在这里很有用,但我担心它会再次影响内部循环,我仍然不确定语法。

【问题讨论】:

    标签: multithreading fortran openmp


    【解决方案1】:

    我无法想象它是如何工作的。无论如何,collapse 语法绝对不支持这一点。

    如果您遇到负载平衡问题,请考虑重新排序循环、使用动态调度、OpenMP 任务或嵌套并行。没有足够的代码来判断哪些可能适用于此。

    【讨论】:

    • 也许是未来的 OpenMP 版本?从技术上讲,应该可以在最内层循环中创建新线程,而外部空闲线程则释放 CPU 容量。
    • 是的,这是可能的,使用嵌套并行。
    • 或者只是并行化内部循环。我只是担心如果只是从 1 到 4 的 j 循环是可并行化的并且如果它运行得太频繁,它可能不够高效。 (但嵌套并行也是如此。)
    • 我认为通常并行化外部循环比并行化内部循环效果更好?但这是围绕内循环的一些蒙蒂卡罗,那么做内循环并行是有意义的。
    【解决方案2】:

    如果1,4 是您在外部循环中使用的实际值,那么我建议只并行化内部循环(可以并行化),因为不会有太多开销。

    另一个建议是交换ki 循环,如果可能的话,所以外部循环将是k 中的循环,ij 中的两个新内部循环可以并行化在一起使用折叠。

    【讨论】:

      【解决方案3】:

      对于这种情况,一种轻量级且统一的方法是使用 OpenMP 任务。
      您可以将它们用于两个并行循环或仅用于内部循环。在第二种情况下,我们将组合for task 构造。该解决方案利用了嵌套并行性,但避免了嵌套并行区域的影响。 taskloop 构造是一种等效且更自动化的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-22
        • 2016-09-30
        • 2019-09-20
        • 1970-01-01
        • 1970-01-01
        • 2016-12-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多