【问题标题】:Openmp schedulingOpenmp 调度
【发布时间】:2013-05-23 12:29:58
【问题描述】:

我有一段带有两个嵌套 for 循环的代码。当第一个步骤很少时,第二个步骤很多,反之亦然。我可以使用 omp for 指令独立运行两个 for 循环,并且我有一致的结果(和一些加速)。但是我想:

  1. 如果第一个步骤有 16 步或更多,则并行运行它
  2. 否则并行运行第二个(但不是第一个,即使它有 8 个步骤)

这不是嵌套并行,因为要么一个循环是并行的,要么另一个是并行的。如果我独立运行它们并运行 top -H 来查看线程,我有时只观察到一个线程,有时会更多(在每种情况下),所以我想做的事情会有意义并且实际上会提高性能吗?

到目前为止,我做了这样的事情:

#pragma omp parallel
{
    #pragma omp for schedule(static,16)
    for(...){
        /* some declarations */
        #pragma omp for schedule(static,16) nowait
        for(...){
            /* ... */
        }
    }
}

不能编译(工作共享区域可能没有紧密嵌套在工作共享、关键、有序、主或显式任务区域内),并且无论如何都不会像我描述的那样运行。 我也尝试过崩溃,但“/* some declarations */”有问题,我想避免它,因为它是 openmp3.0,我不确定目标硬件的编译器是否支持这个。

有什么想法吗?

【问题讨论】:

    标签: parallel-processing openmp


    【解决方案1】:

    您不能嵌套绑定到同一个并行区域的工作共享结构,但您可以使用嵌套并行性并通过if(condition) 子句选择性地停用这些区域。如果condition 在运行时计算为true,则该区域处于活动状态,否则它会串行执行。它看起来像这样:

    /* Make sure nested parallelism is enabled */
    omp_set_nested(1);
    
    #pragma omp parallel for schedule(static) if(outer_steps>=16)
    for(...){
        /* some declarations */
        #pragma omp parallel for if(outer_steps<16)
        for(...){
            /* ... */
        }
    }
    

    这里的缺点是,如果内部区域在运行时不活动,则会引入少量开销。如果您希望提高效率并准备为此牺牲可维护性,那么您可以编写嵌套循环的两种不同实现,并根据outer_steps 的值分支到适当的实现。

    【讨论】:

    • 您好,谢谢。实际上,正如您所说,我最终在 if(){}else{} 中编写了两个不同的并行区域。这很丑陋,但它非常有效。当我要寻找优雅的东西时,我会尝试你的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2021-03-18
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多