OpenMP для зависимых переменных
Это первый раз, когда я использую OpenMP, и я применяю его для Fortran. У меня возникла проблема с настройкой цикла, когда существует переменная, которая требует обновления с ее предыдущего значения. Я пытался с помощью PRIVATE
предложение, но результат далек от результатов последовательных вычислений (без OpenMP).
Я посмотрел где-то на сайте OpenMP, и я нашел одно решение, используя !$OMP PARALLEL DO ORDERED
который, наконец, работает (выдает тот же результат, что и серийный). Но кажется, что при использовании этого, скорость вычислений значительно медленнее, чем просто PRIVATE
пункт.
Есть ли другой способ применить OpenMP в таком случае, чтобы получить максимальную скорость?
Использование кодов ORDERED
вариант.
!$OMP PARALLEL DO ORDERED PRIVATE(i,j)
do i = ca,cb
incre(i) = 0.0d0
value = 17.0d0*li(i)
do j = cx,cy
qx = hi(i) - hj(j)
mij = dsqrt(qx)
if( mij <= value ) then
beta = li(i)*li(j)
!$OMP ORDERED
incre(i) = incre(i) + beta
!$OMP END ORDERED
end if
end do
end do
!$OMP END PARALLEL DO
Только коды, использующие PRIVATE
пункт
!$OMP PARALLEL DO PRIVATE(i,j,incre,value,beta)
do i = ca,cb
incre(i) = 0.0d0
value = 17.0d0*li(i)
do j = cx,cy
qx = hi(i) - hj(j)
mij = dsqrt(qx)
if( mij <= value ) then
beta = li(i)*li(j)
incre(i) = incre(i) + beta
end if
end do
end do
!$OMP END PARALLEL DO
1 ответ
Как отметил в своих комментариях Франсуа, qx
а также mij
должен быть частным потоком:
!$OMP PARALLEL DO PRIVATE(i,j,value,beta,qx,mij)
do i = ca,cb
incre(i) = 0.0d0
value = 17.0d0*li(i)
do j = cx,cy
qx = hi(i) - hj(j)
mij = dsqrt(qx)
if( mij <= value ) then
beta = li(i)*li(j)
incre(i) = incre(i) + beta
end if
end do
end do
!$OMP END PARALLEL DO
incre
не должен быть закрытым, так как доступ к нему осуществляется только через индекс i
, поэтому все потоки обращаются к разным его частям. Однако, если вам необходимо получить доступ к элементам впоследствии, убедитесь, что они являются общедоступными (общими).