我有一段带有两个嵌套for循环的代码。当第一个步骤很少时,第二个步骤很多,反之亦然。我可以独立运行omp for omp for循环指令,并且我有一致的结果(以及一些加速)。不过我想:
这不是嵌套并行性,因为一个循环是平行的或另一个循环。如果我独立运行它们并运行顶部-H来查看线程,我有时会观察到一个线程,有时甚至更多(在每种情况下),所以我想做的事情会有意义并且实际上会提高性能吗?
到目前为止,我做了类似的事情:
#pragma omp parallel
{
#pragma omp for schedule(static,16)
for(...){
/* some declarations */
#pragma omp for schedule(static,16) nowait
for(...){
/* ... */
}
}
}
不编译(工作共享区域可能不会紧密嵌套在工作共享,关键,有序,主要或显式任务区域内)并且不会像我描述的那样表现。 我也试过崩溃,但是“/ *一些声明* /”有问题,我想避免它,因为它是openmp3.0而且我不确定目标硬件的编译器会支持这个。
有什么想法吗?
答案 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
的值分支到适当的实现。