Низкая производительность вложенного цикла DO с использованием OpenMP для FORTRAN90

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

    !$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. Одно ядро ​​дает лучшую производительность, чем параллельный код. Пожалуйста, подскажите, какую ошибку я здесь делаю..


person Narender Koosukuntla    schedule 02.11.2011    source источник


Ответы (2)


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

Сказав это, я могу получить небольшое (~ 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 и требует больших вычислительных ресурсов, все было бы иначе; но копия памяти вряд ли сильно ускорится.

person Jonathan Dursi    schedule 02.11.2011

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

person FrenchKheldar    schedule 14.11.2011