c - OpenMP 通过缩减来折叠并行循环

标签 c multithreading for-loop openmp reduction

我正在尝试使用 openMP 并行化这个崩溃循环,但这就是我得到的: “smooth.c:47:6:错误:‘sum’ sum = 0 之前没有足够的完美嵌套循环;”

有人知道并行化的好方法吗?我在这个问题上被困了两天。

这是我的循环:

long long int sum;  
#pragma omp parallel for collapse(3) default(none) shared(DY, DX) private(dx, dy) reduction(+:sum) 
            for (y = 0; y < height; y++) {
                for (x = 0; x < width; x++) {
                     sum = 0;
                    for (d = 0; d < 9; d++) {
                        dx = x + DX[d];
                        dy = y + DY[d];
                        if (dx >= 0 && dx < width && dy >= 0 && dy < height)
                            sum += image(dy, dx);
                    }
                    smooth(y, x) = sum / 9;
                }
            }

完整代码: https://github.com/fernandesbreno/smooth_

最佳答案

i'm trying to parallelize this collapse loops with openMP, but this is what i got: "smooth.c:47:6: error: not enough perfectly nested loops before ‘sum’ sum = 0;"

您无法折叠三个循环级别,因为第三个级别并未完美嵌套在第二个级别内。有

sum = 0;

之前和

smooth(y, x) = sum / 9;

在中间循环的后面。 (我认为 smooth() 是一个宏,否则赋值没有意义。不过,不要这样做,因为它会令人困惑。)

考虑如何利用您对问题结构和细节的了解,手动将该循环嵌套重写为等效的单个循环。我认为这样做是具有挑战性的,而且结果将不可避免地存在数据依赖性。但是,如果您设法在不引入依赖项的情况下做到这一点,那么瞧!您有一个扁平循环可以并行化,无需折叠。

然而,您最简单的前进方法可能是仅折叠两层而不是三层。此外,您想要与根本不折叠进行比较,因为与仅并行化外循环相比,完全不清楚折叠是否会产生改进,并且折叠甚至可能更糟

但是,如果您必须让 OpenMP 折叠嵌套的所有三层,那么您需要采用我上面调用的两行代码,并将它们从循环嵌套中提出。也许您可以通过完全摆脱 sum 并直接使用结果栅格来实现这一点。同样,这并不一定会带来改进。

关于c - OpenMP 通过缩减来折叠并行循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56068328/

相关文章:

java - 构造函数中的同步块(synchronized block)

JavaScript For 循环问题 : Why Am I getting a syntax error?

java - 在 java 8 foreach 中使用字符串替换

c - WDM驱动与用户态通信: best practices and callback questions

c - 即使代码编译也出现运行错误

谁能告诉我 pragma 语句的用法

java - 如何让一个线程等待并执行另一个???

c - 函数指针线程安全吗?

Java除法循环

c - gcc 中的无穷大值