Openmp调度

时间:2013-05-23 12:29:59

标签: parallel-processing openmp

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

  1. 如果有16步或更多步骤,则并行运行第一个
  2. 否则并行运行第二个(即使它有8个步骤,但不是第一个)
  3. 这不是嵌套并行性,因为一个循环是平行的或另一个循环。如果我独立运行它们并运行顶部-H来查看线程,我有时会观察到一个线程,有时甚至更多(在每种情况下),所以我想做的事情会有意义并且实际上会提高性能吗?

    到目前为止,我做了类似的事情:

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

    不编译(工作共享区域可能不会紧密嵌套在工作共享,关键,有序,主要或显式任务区域内)并且不会像我描述的那样表现。 我也试过崩溃,但是“/ *一些声明* /”有问题,我想避免它,因为它是openmp3.0而且我不确定目标硬件的编译器会支持这个。

    有什么想法吗?

1 个答案:

答案 0 :(得分: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的值分支到适当的实现。