OpenMP свернул параллельный цикл с сокращением - PullRequest
0 голосов
/ 10 мая 2019

Я пытаюсь распараллелить эти циклы свертывания с openMP, но вот что я получил: "smooth.c: 47: 6: ошибка: недостаточно идеально вложенных циклов перед '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_

1 Ответ

1 голос
/ 10 мая 2019

Я пытаюсь распараллелить эти циклы свертывания с openMP, но вот что я получил: "smooth.c: 47: 6: ошибка: недостаточно идеально вложенных циклов перед" sum "’ sum = 0; "

Вы не можете свернуть три уровня цикла, потому что третий уровень не полностью вложен во второй. Есть

sum = 0;

до него и

smooth(y, x) = sum / 9;

после него в средней петле. (Полагаю, smooth() - это макрос, иначе назначение не имеет смысла. Но не делайте этого, потому что это сбивает с толку.)

Подумайте, как бы вы переписали это гнездо цикла в эквивалентный отдельный цикл вручную, используя свои знания о структуре проблемы и ее деталях. Я утверждаю, что это было бы сложно сделать, и что результат, кроме того, будет иметь неизбежные зависимости данных. Но если вам удалось сделать это без введения зависимостей, то вуаля! У вас есть одна плоская петля для распараллеливания, не требуется свертывание.

Однако самым простым способом продвижения вперед, вероятно, было бы падение только двух уровней вместо трех. Более того, вы хотите сравнить с отсутствием коллапса вообще, поскольку не совсем понятно, что коллапс даст улучшение по сравнению с распараллеливанием только внешнего цикла, и коллапс может быть даже хуже .

Но если вам нужно, чтобы OpenMP свернул все три уровня гнезда, то вам нужно взять две строки, которые я назвал выше, и вынуть их из гнезда петли. Возможно, вы могли бы сделать это частично, полностью избавившись от sum и работая непосредственно с результирующим растром. Опять же, это не обязательно приведет к улучшению.

...