gpt4 book ai didi

c++ - OpenMP嵌套无法关闭

转载 作者:行者123 更新时间:2023-12-01 14:43:41 32 4
gpt4 key购买 nike

我正在尝试使用OpenMP(4.5,通过GCC 7.2.0)管理嵌套的并行区域,但是在关闭嵌套时遇到了一些问题。

示例程序:

#include <stdio.h>
#include <omp.h>

void foobar() {
int tid = omp_get_thread_num();
#pragma omp parallel for
for (int i = 0; i < 4; i++) {
int otid = omp_get_thread_num();
printf("%d | %d\n", tid, otid);
}
}

int main(void) {
omp_set_nested(0);
#pragma omp parallel
{
foobar();
}
printf("\n");
foobar();
return 0;
}

我期望在这里发生的是foobar()上的并行区域和非并行调用都将吐出4行,这与
// parallel region foobar()
0 | 0
1 | 1
2 | 2
3 | 3
// serial region foobar()
0 | 0
0 | 1
0 | 2
0 | 3

因为我不允许嵌套并行处理。但是,我在并行区域中获得了16 strip 有正确TID的行,但OTID始终为0(即,每个线程产生自己的4条,并在其上执行整个循环),而我得到4条外部(即,并行为产生了4个线程,正如我所期望的那样)

我觉得我在这里遗漏了一些很明显的东西,有人可以帮我找个亮点吗?禁用嵌套是否应该将那个并行的omp变成一个普通的omp,并相应地分配工作?

最佳答案

您的问题来自错误的假设,即将解释omp for指令并在线程之间分配相应的工作,而不管哪个parallel区域处于 Activity 状态。不幸的是,在您的代码中,omp for仅与在函数parallel中声明的foobar()区域相关联。因此,当激活该区域时(意味着由于您禁用了嵌套并行性,因此当未从另一个foobar()区域调用parallel时),您的循环将分布在新生成的线程之间。但是,如果不是这样,因为从另一个foobar()区域调用了parallel,则omp for会被忽略,并且循环不会在调用线程之间分配。因此,它们每个都执行整个循环,从而导致您看到的printf()的复制。

可能的解决方案是这样的:

#include <stdio.h>
#include <omp.h>

void bar(int tid) {
#pragma omp for
for (int i = 0; i < 4; i++) {
int otid = omp_get_thread_num();
printf("%d | %d\n", tid, otid);
}
}

void foobar() {
int tid = omp_get_thread_num();
int in_parallel = omp_in_parallel();
if (!in_parallel) {
#pragma omp parallel
bar(tid);
}
else {
bar(tid);
}
}

int main() {
#pragma omp parallel
foobar();
printf("\n");
foobar();
return 0;
}

我真的没有找到完全令人满意的解决方案,但现在没有更好的解决方案。也许以后我会有所启发...

编辑:好,我有另一个想法:从实际的 parallel区域调用函数时,仅使用一个 Activity 线程,就可以以另一种方式来执行此方法并强制嵌套并行性:
#include <stdio.h>
#include <omp.h>

void foobar() {
int tid = omp_get_thread_num();
omp_set_nested(1);
#pragma omp single
#pragma omp parallel for
for (int i = 0; i < 4; i++) {
int otid = omp_get_thread_num();
printf("%d | %d\n", tid, otid);
}
}

int main() {
#pragma omp parallel
foobar();
printf("\n");
foobar();
return 0;
}

这次代码看起来很好,没有任何重复,并给出了(例如):
$ OMP_NUM_THREADS=4 ./nested
3 | 2
3 | 3
3 | 1
3 | 0

0 | 3
0 | 1
0 | 0
0 | 2

关于c++ - OpenMP嵌套无法关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59638111/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com