Лучший способ распараллелить этот цикл в OpenMP

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

thread = omp_get_max_threads ( )
chunk=jmaxm/thread
c$omp parallel shared (zetun,zetvn) private (i, j)
c$omp do schedule(DYNAMIC,chunk) ORDERED
    do j=2,jmaxm
        jm=j-1
        jp=j+1
             do i=2,imaxm
                if (rmask(i,j).eq.1.0)then
             im=i-1
             ip=i+1
             zetun(i,j)=
           +  (un(im,j,km)+un(ip,j,km)-2.*un(i,j,km))*recdx2
           +  + ((un(i,jp,km)-un(i,j,km))-
           +  (un(i,j,km)-un(i,jm,km)))*recdy2

             zetvn(i,j)=
           +  ((vn(ip,j,km)-vn(i,j,km))-
           +  (vn(i,j,km)-vn(im,j,km)))*recdx2
           +  + (vn(i,jp,km)+vn(i,jm,km)-2.*vn(i,j,km))*recdy2
              endif

        end do

    end do
 c$omp end do nowait
 c$omp end parallel

Теперь я добавляю модифицированный код следующим образом, но, похоже, все еще не делаю никаких улучшений. ИЗМЕНЕННЫЙ КОД:

  c$omp parallel shared (zetun,zetvn) private (i,j,jm,jp,im,ip,km)

  c$omp do schedule(DYNAMIC,20) 
   do j=2,jmaxm
        jm=j-1
        jp=j+1
             do i=2,imaxm
                if (rmask(i,j).eq.1.0)then
             im=i-1
             ip=i+1
             zetun(i,j)=
           +  (un(im,j,km)+un(ip,j,km)-2.*un(i,j,km))*recdx2
           +  + ((un(i,jp,km)-un(i,j,km))-
           +  (un(i,j,km)-un(i,jm,km)))*recdy2

             zetvn(i,j)=
           +  ((vn(ip,j,km)-vn(i,j,km))-
           +  (vn(i,j,km)-vn(im,j,km)))*recdx2
           +  + (vn(i,jp,km)+vn(i,jm,km)-2.*vn(i,j,km))*recdy2
              endif

           end do

    end do
c$omp end do
c$omp end parallel

person Jovi Dsilva    schedule 22.12.2013    source источник


Ответы (1)


Код недействителен. jm, jp, im и ip должны быть как минимум приватными. Кроме того, почему вам требуется ordered? Это определенно замедляет его. Кроме того, hhy schedule dynamic с таким большим куском? Просто используйте static.

Кроме того, используйте отступ строки при кодировании или, по крайней мере, при представлении кода другим.

person Vladimir F    schedule 22.12.2013
comment
Я сделал, как сказал, но теперь это занимает еще больше времени, что насчет того, что сейчас нужно? - person Jovi Dsilva; 22.12.2013
comment
@HighPerformanceMark Да, тот же код выше, я добавил jm, jp, im и ip как частные, но все равно он медленный, также изменил ДИНАМИЧЕСКИЙ, фрагмент на СТАТИЧЕСКИЙ - person Jovi Dsilva; 22.12.2013
comment
Поскольку самые внутренние вычисления маскируются и, следовательно, вычислительная нагрузка зависит от содержимого rmask, планирование static может быть не оптимальным. Но и dynamic с таким размером чанка тоже нет. - person Hristo Iliev; 22.12.2013
comment
@HristoIliev Значит, мне не следует использовать Расписание? - person Jovi Dsilva; 22.12.2013
comment
@JoviDsilva, когда есть некоторый вычислительный дисбаланс, помогает dynamic планирование. Но в вашем случае вы устанавливаете размер фрагмента равным #iterations/#threads, что означает, что каждый поток получает фрагмент итерации одинакового размера. То же самое верно для планирования static с размером фрагмента по умолчанию. Без какой-либо спецификации планирования большинство сред выполнения OMP по умолчанию имеют значение static (хотя это и не гарантируется стандартом). Вы все еще можете использовать динамический, но использовать меньший размер фрагмента, в противном случае это практически не имеет смысла. Выбор правильного размера фрагмента немного сложен и может потребовать экспериментов. - person Hristo Iliev; 22.12.2013
comment
@HristoIliev Спасибо, я попробую с небольшим размером фрагмента, в цикле jmax = 236, так что размер фрагмента 20 подходит? - person Jovi Dsilva; 23.12.2013
comment
Сначала убедитесь, что вы исправили основные ошибки. В противном случае играйте с размером чанка как хотите и смотрите результат, у нас нет хрустального шара. Возможность увидеть исправленную версию кода может помочь. - person Vladimir F; 23.12.2013
comment
Я не понимаю, почему вы используете так много опций OMP... Например, NOWAIT, конечно, бесполезен в вашем примере. Единственное, что я всегда использую, это DEFAULT(NONE), что особенно интересно для немедленного обнаружения проблем с переменными im и ip. - person Francois Jacq; 23.12.2013
comment
@VladimirF Я добавил модифицированный код, я пробовал статический, но без особого эффекта. Но я видел, что итерации были разделены равномерно. Я тоже пытаюсь использовать DYNAMIC. - person Jovi Dsilva; 23.12.2013
comment
Пожалуйста, используйте отступы ради бога! - person Vladimir F; 23.12.2013
comment
Чтобы увеличить масштабируемость, попробуйте свернуть (2), чтобы объединить два цикла. - person Francois Jacq; 24.12.2013