#openmp
Вопрос:
Я пытаюсь распараллелить следующий цикл, используя OpenMP target
для запуска на графическом процессоре. Проблема, которую я вижу, заключается в том, что я не могу найти способ k
последовательного выполнения цикла на графическом процессоре. В OpenACC
было бы что-то вроде !$acc loop seq
. Есть ли аналогичный способ сделать это в режиме разгрузки OpenMP?
do k = 2, nelem do j = 1, ny do i = 1, nx v(i, j, k) = v(i,j,k-1) kk*(N(i,j,k)-c2)**c3 N(i, j, k) = N(i, j, k)*( 1.0D0 - rpm*c(i,j,k) v(i,j,k) ) end do end do end do
Я пытался сделать что-то вроде
!$omp target do k = 2, nelem !$omp teams distribute parallel do collapse(2) do j = 1, ny do i = 1, nx v(i, j, k) = v(i,j,k-1) kk*(N(i,j,k)-c2)**c3 N(i, j, k) = N(i, j, k)*( 1.0D0 - rpm*c(i,j,k) v(i,j,k) ) end do end do !$omp end teams distribute parallel do end do !$omp end target
но что-то в этом не так.
Комментарии:
1. Я пока не уверен в ответе, но даже если это возможно сделать с помощью OpenMP, это приведет к созданию неэффективного кода. Загрузка памяти не будет непрерывной в памяти, и вероятность того, что компилятор или программное обеспечение смогут понять шаблон и выполнить локальную транспозицию, очень мала. На самом деле серверная часть CUDA генерирует инструкцию, которая неэффективно выполняется на довольно новых графических процессорах (например, P100). Полученный код может быть медленнее, чем код, выполняемый на процессорах. Если вы хотите быть эффективным, гораздо лучше выполнить транспозицию данных
v
с использованием общей памяти .