Последовательное выполнение цикла в целевом объекте OpenMP

#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 с использованием общей памяти .