OpenMP 减少并行循环

OpenMP collapsed parallel loop with reduction

我正在尝试使用 openMP 并行化这个崩溃循环,但这就是我得到的: "smooth.c:47:6: error: not enough perfectly nested loops before ‘sum’ sum = 0;"

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

这是我的循环:

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 并直接使用结果栅格来部分做到这一点。同样,这不一定会产生改善。