Низкая производительность вложенного цикла DO с использованием OpenMP для FORTRAN90 - PullRequest
1 голос
/ 02 ноября 2011

Я пытаюсь распараллелить часть моего кода, которая выглядит следующим образом

    !$OMP PARALLEL PRIVATE(j,x,y,xnew, ynew) SHARED(xDim, yDim, ex, f, fplus)
    !$OMP DO
    DO j = 1, 8
        DO y=1, yDim
            ynew = y+ey(j)
            DO x=1, xDim
                xnew = x+ex(j)
                IF ((xnew >= 1 .AND. xnew <= xDim) .AND.  (ynew >= 1 .AND. ynew <= yDim))  f(xnew,ynew,j)=fplus(x,y,j)
            END DO
        END DO
    END DO
    !$OMP END DO
    !$OMP END PARALLEL

Я новичок в OpenMP и FORTRAN. Одноядерное ядро ​​дает лучшую производительность, чем параллельный код.Пожалуйста, подскажите, какую ошибку я здесь делаю ..

Ответы [ 2 ]

3 голосов
/ 02 ноября 2011

Проблема здесь в том, что вы просто копируете фрагмент массива - здесь нет ничего реально ограниченного ЦП, с которым разделение между ядрами значительно поможет.В конечном счете, эта проблема связана с памятью, копируя данные из одного фрагмента памяти в другой, и увеличение количества работающих одновременно процессоров, вероятно, только увеличивает конкуренцию.

Сказав это, я могу стать маленьким (~ 10%)ускорения, если я немного переделываю цикл, чтобы получить оператор if из цикла.Это:

CALL tick(clock)
!$OMP PARALLEL PRIVATE(j,x,y,xnew, ynew) SHARED(ex, ey, f, fplus) DEFAULT(none)
!$OMP DO
DO j = 1, 8
    DO y=1+ey(j), yDim
        DO x=1+ex(j), xDim
            f(x,y,j)=fplus(x-ex(j),y-ey(j),j)
        END DO
    END DO
END DO
!$OMP END DO
!$OMP END PARALLEL
time2 = tock(clock)

или это:

CALL tick(clock)
!$OMP PARALLEL PRIVATE(j,x,y,xnew, ynew) SHARED(ex, ey, f, fplus) DEFAULT(none)
!$OMP DO
DO j = 1, 8
    f(1+ex(j):xDim, 1+ey(j):yDim, j) = fplus(1:xDim-ex(j),1:yDim-ey(j),j)
ENDDO
!$OMP END DO
!$OMP END PARALLEL
time3 = tock(clock)

сделать очень скромные улучшения.Если бы fplus был функцией аргументов x, y и j и требовал значительных вычислительных ресурсов, все было бы иначе;но копия памяти вряд ли сильно ускорится.

0 голосов
/ 14 ноября 2011

Ваша производительность также будет зависеть от размеров петель.У вас есть правильное расположение циклов, с самым правым указателем на внешнем цикле для более оптимизированного доступа к памяти.Если эти циклы невелики и вся память может поместиться в кэш одного процессора, вероятно, не будет никакого улучшения производительности при использовании OpenMP.Как вы увидели, вы можете увидеть снижение производительности из-за издержек OpenMP, таких как создание / уничтожение потоков.И в будущем старайтесь избегать выражений IF внутри вложенных циклов, они действительно повредят вашей производительности!

...