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, поэтому все потоки обращаются к разным его частям. Однако, если вам необходимо получить доступ к элементам впоследствии, убедитесь, что они являются общедоступными (общими).

Другие вопросы по тегам