2015-09-11 2 views
3

У меня есть потенциально простой вопрос, но, глядя на СО, я не мог найти вопросов, которые задавали совершенно то же самое. Мой вопрос: будет ли предложение collapse в коде OpenMP ниже правильно обрабатывать обе внутренние петли? Или он только рухнет с первым внутренним циклом?Специальный случай краха OpenMP

!$omp parallel do collapse(2) private(iy, ix, iz) 
do iy = 1, ny 
    do ix = 1, nx 
     ! stuff 
    enddo 
    do iz = 1, nz 
     ! different stuff 
    enddo 
enddo 
!$omp end parallel do 

Этот код компилируется для меня и, очевидно, показывает преимущества распараллеливания. Однако я знаю, что в стандарте указано:

Все петли, связанные с конструкцией цикла, должны быть полностью вложены; то есть не должно быть промежуточного кода или любой директивы OpenMP между любыми двумя циклами.

Так что моя реакция кишки заключается в том, что OpenMP только сворачивает первый внутренний контур (ix). Но тогда как он обрабатывает второй внутренний цикл (iz)?

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

!$omp parallel private(iy, ix, iz) 
!$omp do collapse(2) 
do iy = 1, ny 
    do ix = 1, nx 
     ! stuff 
    enddo 
enddo 
!$omp end do nowait 

!$omp do collapse(2) 
do iy = 1, ny 
    do iz = 1, nz 
     ! different stuff 
    enddo 
enddo 
!$omp end do nowait 
!$omp end parallel do 
+0

nowait на втором деле ничего не делает, поскольку параллельный конец имеет барьерную семантику. – Jeff

ответ

4

Первый внутренний цикл кода вмешиваясь между внешним контуром и второй внутренняя петля (как я ее понимаю). Если nznx, у вас нет прямоугольных петель. В любом случае семантика программы заключается в том, что первый внутренний цикл должен завершиться до начала второго внутреннего цикла; он может выполнять промежуточные вычисления, которые использует второй цикл. Данная реализация OpenMP может делать то, что вы хотите - я не пытался проверить это.

Обратите внимание, что второй пример изменяет семантику программы: все ix петли выполнить, а затем все iz петель, а не каждой ix цикла с последующим каждой iz петли для того же значения iy. Это должно быть безопасным, если вы можете распараллелить цикл ix, поскольку это можно сделать только в том случае, если ни один из вычислений ix не зависит от любого вычисления iz, но может оказаться не столь эффективным, если петли iz собираются повторно использовать одни и те же данные. Таким образом, правильная семантика будет зависеть от того, что должно произойти до того, как данный цикл может работать. Нужно ли, чтобы петли iz нуждались в петлях ix, которые запускались сначала для того же значения iy? Если нет, вы можете использовать вложенный параллелизм.

Обратите внимание на петли Сворачивание: Loop коллапса обычно означает, что вы берете вложенную пару петель, таких как,

for (i=0;i<100;++i) 
    for (j=0;j<50;++j) 

И превратить их в единый контур, как:

for (ij=0;ij<5000;++ij) 

Если у вас есть две разные внутренние петли с разными индексами, вы не можете этого сделать, и, кроме того, компилятор не может автоматически изменить порядок выполнения, как предлагается, потому что это изменяет семантику программы. Я не уверен, что каждая реализация OpenMP делает с этим кодом, но я уверен, что это не работает так, как вы надеялись.

+0

Я не согласен с некоторыми моментами.Аргумент «прямоугольные петли» ошибочен, потому что если (как я надеюсь) каждый внутренний цикл разваливается независимо, то две петли являются прямоугольными. Вот как я лично интерпретирую «коллапс (2)» как минимум в этом контексте. – NoseKnowsAll

+0

Кроме того, обратите внимание на то, что после первого цикла существует «end do nowait», в котором я надеюсь получить конечный результат. Это означает, что не каждая итерация первого цикла гарантированно заканчивается до того, как поток начнет свою часть второго цикла. Ака семантика того, на что я надеюсь, ответ: второй цикл не зависит от вычисления первого цикла. – NoseKnowsAll

+0

Хорошо. Я не думаю, что компилятор может автоматически вывести, что 'nowait' должен быть там. – Davislor