2016-09-19 3 views
1

Я написал этот вопрос с точки зрения 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

Отложив в сторону, что оба вычисления в фрагментах не имеют смысла (ОК, это просто показать, что мы делаем некоторые вычисления), оказывается, что ** метод 1 ** и ** метод 2 ** не являются эквивалентными, потому что (в этом случае много). Таким образом, ваше утверждение о том, что «метод 2 превосходит метод 1», весьма сомнительно, поскольку ** метод 2 ** неверен, если ссылка является результатом, полученным из ** метода 1 ** (если только 'a = b = 0').Я знаю, это не ваш вопрос, но я все верю до эффективности. – Gilles

+1

Что именно вы подразумеваете под * «петлями параллелизма MPI» *? Такого нет. –

ответ

4

Мое понимание состоит в том, что различие, которое вы ищете (метод 2 и метод 3), не зависит от распараллеливания.

Поясню:

Метод 3, возможно, есть еще над головой из-за вызова процедуры, которая не присутствует в метод 2. Я говорю, возможно, потому, что я не знаком с процедурой указателей, однако, я думаю, что оптимизация компилятором не будет включать вызов процедуры, если вы используете указатели на процедуры.

Это накладные расходы из-за вызова процедуры абсолютно не зависит от распараллеливания. Вы все равно будете иметь его в последовательном коде. Он не является частью задержки параллелизации.

Теперь я беру на себя риск вернуться к варианту, который вам не нравится: попробуйте и посмотрите. Я беру этот риск, потому что считаю, что то, что вы показали, является лишь иллюстрацией вашей проблемы и что ваш фактический случай более сложный. Когда вы попадаете в сложные ситуации, вы можете быть удивлены, что заключение между методами 1 и 2 уже недействительно. Это может сильно зависеть от проблемы, с которой вы столкнулись. Вывод для одного случая не будет выполняться для другого. Такие интеллектуальные, как компиляторы в настоящее время, они не поймут все. В информатике есть такое понятие кэш-памяти, которое когда-то не совсем понятно, но я не буду вдаваться в подробности. Вы можете иметь случай, когда каждый отдельный цикл (данные и/или код) метода 1 хранятся в кэш-памяти, в то время как цикл объединения случая 2 не сохраняется в кэш-памяти. Простейшая иллюстрация - это случай, когда метод 2 испытывает ошибку кэша внутри внутреннего цикла, а метод 1 - нет. В этом случае вы увидите, что метод 1 значительно превосходит метод 2 для больших границ цикла.

Именно здесь Try and see становится стандартом, и именно это происходит в большинстве случаев для случаев реальной жизни.

+1

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

Смежные вопросы