Я написал этот вопрос с точки зрения Fortran, но вопросы не ограничиваются одним только Fortran (следовательно, тегом C++).Меры по уменьшению латентности openmp
У меня есть два вопроса. Я читал, что латентность существует при запуске и остановке параллельных циклов OpenMP here. Мои вопросы:
Q1) Какие практические меры существуют для смягчения латентности OpenMP?
Q2) Какой из следующих методов будет работать лучше?
Метод 1
x = 1.0; y = 2.0
!$OMP PARALLEL DO
do k=1,Nz; do j=1,Ny; do i=1,Nx
x(i,j,k) = x(i,j,k)+y(i,j,k)
enddo; enddo; enddo
!$OMP END PARALLEL DO
!$OMP PARALLEL DO
do k=1,Nz; do j=1,Ny; do i=1,Nx
x(i,j,k) = x(i,j,k)*y(i,j,k)
enddo; enddo; enddo
!$OMP END PARALLEL DO
! (x should = 6.0 at this point)
Метод 2
x = 1.0; y = 2.0
!$OMP PARALLEL DO
do k=1,Nz; do j=1,Ny; do i=1,Nx
x(i,j,k) = x(i,j,k)+y(i,j,k)
x(i,j,k) = x(i,j,k)*y(i,j,k)
enddo; enddo; enddo
!$OMP END PARALLEL DO
! (x should = 6.0 at this point)
Метод 3
1) Создать объект, содержащий массив процедур
2) Вызвать массив процедур следующим
x = 1.0; y = 2.0
!$OMP PARALLEL DO
do k=1,Nz; do j=1,Ny; do i=1,Nx
do t=1,procedure_array%N
call procedure_array%single_procedure(t)%P(x(i,j,k),y(i,j,k))
enddo
enddo; enddo; enddo
!$OMP END PARALLEL DO
! (x should = 6.0 at this point)
Давайте предположим, что procedure_array%N = 2
и
procedure_array%single_procedure(1)
procedure_array%single_procedure(2)
Точка подпрограммы add
(x=x+y
) и multiply
(x=x*y
) соответственно.
3) очистка (DEALLOCATE)
Комментарии
Во-первых, ясно, что метод 2 превосходит метод 1, так что я действительно заинтересован в сравнении метода 2 к методу 3. Во-вторых, я знаю, что «попробовать и посмотреть» - это правильный ответ, но я хочу знать, существуют ли конкретные примеры метода 3, используемые на практике (или в промышленности) или концептуальные причины, почему метод 3 хуже, чем метод 2 (например, накладные расходы из-за многих вызовов процедур). Наконец, если есть какая-то особая осторожность, которая может быть предпринята (например, путем конкретного указания конкретных потоков), чтобы сделать методы 2 и 3 практически эквивалентными, каковы они?
Я ценю любую помощь!
Обновления
В свете замечаний, я сделал следующие исправления.
- модифицировали операций (спасибо, @Gilles)
- удалены все связанные с MPI, это действительно OpenMP вопрос (спасибо, @Vladimir)
- Добавлено разъяснение ниже (мои собственные реализации)
И спасибо, @innoSPG, о вашем ответе о кеш-памяти (и ошибке кэша), что было очень информативно и полезно!
Разъяснение
Наконец, из комментариев, я понял, что в центре внимания этот вопрос на самом деле о вызове процедуры, а не строго связано с OpenMP распараллеливания. Тем не менее, я оставил инструкции openmp, потому что это то, что происходит в моем более сложном приложении, которое я хотел бы сохранить как можно больше. Похоже, из комментария @ Chaosit, что вызов процедуры потребует накладных расходов, замедления метода 3. Есть ли способ обойти это?
Также, пожалуйста, исправьте меня, если я ошибаюсь, но я верю, что две операции в методе 2 будут выполнены в письменном порядке, в результате чего будет получено правильное окончательное значение x
.
Отложив в сторону, что оба вычисления в фрагментах не имеют смысла (ОК, это просто показать, что мы делаем некоторые вычисления), оказывается, что ** метод 1 ** и ** метод 2 ** не являются эквивалентными, потому что (в этом случае много). Таким образом, ваше утверждение о том, что «метод 2 превосходит метод 1», весьма сомнительно, поскольку ** метод 2 ** неверен, если ссылка является результатом, полученным из ** метода 1 ** (если только 'a = b = 0').Я знаю, это не ваш вопрос, но я все верю до эффективности. – Gilles
Что именно вы подразумеваете под * «петлями параллелизма MPI» *? Такого нет. –