【发布时间】:2022-01-10 02:19:05
【问题描述】:
在我的 c++ 实现中,我有一个递归函数,我在循环中调用这个递归函数。我想使用 OpenMP 创建并行性。
func caller(){
#pragma omp parallel
{
#pragma omp for nowait
for (int i = 0; i < num; i++){
#pragma omp single
recursive_func(n);
}
}
void recursive_func(n){
if (x){
#pragma omp task
recursive_func(n-1);
}
else{
#pragma omp task
recursive_func(n-2);
}
}
我基本上希望外循环由多个线程执行,但是当涉及到递归函数时,只有一个线程应该开始执行它,然后递归调用应该由新任务处理(这将与 @ 987654323@)
但是,我收到此编译错误:
错误:工作共享区域可能没有紧密嵌套在 工作共享、“关键”、“有序”、“大师”、明确的“任务”或 任务循环区域
68 | #pragma omp single
【问题讨论】:
-
1.我想知道
nowait是否是问题2。在循环之前执行主体single. How about if you put thesingle 并且不使其并行的并行循环没有多大意义? -
@VictorEijkhout 是的,我明白你的意思,单曲破坏了平行的目的。我只是想让许多线程同时执行递归函数,并且每次都由不同的任务执行递归函数
-
@codertryer 如果您想在工作共享结构中创建新任务,您必须在递归函数中打开一个新的
omp parallel部分。但是,我建议不要这样做,因为它只会使 CPU 过载,并且 OpenMP 将始终启动新线程,而不是将其线程池用于嵌套并行部分。你真正想解决什么问题? -
@Homer512 我同意在嵌套情况下创建新线程(尽管我记得这可以针对 GCC/Clang 进行调整)。然而,这里没有(需要)嵌套:任务可以被调度并行for循环,这不是嵌套。在这种情况下,并行部分创建隐式任务(parallel for 指令仅共享工作),并且每个隐式任务的同级任务在设计上是独立的(尽管在这里这是一个问题,因为 OP 希望它们以互斥)。这在 OpenMP 5.2 规范的第 1.3、17.1 和 15.9.5 节中有详细说明。
-
@JérômeRichard 好吧,在这种情况下你似乎不需要嵌套是正确的。作为记录,在第 429 行 code.woboq.org/gcc/libgomp/team.c.html 中解释了嵌套线程缺乏池化
标签: c++ recursion parallel-processing openmp shared-memory