Матрица доступа CUDA, хранящаяся в ОЗУ и возможность реализации

#c #cuda #numerical-computing

#c #cuda #числовые вычисления

Вопрос:

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

Сердцем моего кода является следующая функция. Записи представляют собой две точки к векторам. N_mesh_points_x,y,z заданы ли заранее целые weights_x,y,z числа, являются ли матрицы столбцов kern_1 экспоненциальной функцией и table_kernel функцией, которая обращается к матрице объемом 50 Гб, хранящейся в ОЗУ и предварительно вычисленной.

 void Kernel::paralel_iterate(std::vector<double>* K1, std::vector<double>* K2 )
{
  double r, sum_1 = 0 , sum_2 = 0;
  double phir;

    for (int l = 0; l < N_mesh_points_x; l  ){
      for (int m = 0; m < N_mesh_points_y; m  ){
        for (int p = 0; p < N_mesh_points_z; p  ){
        sum_1 = 0;
        sum_2 = 0;

        #pragma omp parallel for schedule(dynamic) private(phir) reduction( : sum_1,sum_2)
        for (int i = 0; i < N_mesh_points_x; i  ){
          for (int j = 0; j < N_mesh_points_y; j  ){
            for (int k = 0; k < N_mesh_points_z; k  ){
               
               if (!(i==l) || !(j==m) || !(k==p)){
               phir = weights_x[i]*weights_y[j]*weights_z[k]*kern_1(i,j,k,l,m,p);
               sum_1  = phir * (*K1)[position(i,j,k)];
               sum_2  = phir;
              }

             }
           }
         }
        (*K2)[ position(l,m,p)] = sum_1   (table_kernel[position(l,m,p)] - sum_2) * (*K1)[position (l,m,p)];
    }
  }
}

return;
}
 

Мои вопросы:

  • Могу ли я запрограммировать, по крайней мере, центральную часть этой функции, в CUDA? Я только распараллелил с OpenMP внутренние циклы, потому что давал неправильный ответ, когда распараллеливал все циклы.
  • Функция table_kernel , которая обращается к большой матрице, матрица слишком велика, чтобы ее можно было сохранить в памяти моей видеокарты, поэтому файл останется в ОЗУ. Это проблема? Может ли CUDA легко получить доступ к файлам в ОЗУ? Или это невозможно сделать, и все файлы, необходимые для хранения внутри видеокарты?

Ответ №1:

Могу ли я запрограммировать, по крайней мере, центральную часть этой функции, в CUDA? Я только распараллелил с OpenMP внутренние циклы, потому что давал неправильный ответ, когда распараллеливал все циклы.

Да, вы должны иметь возможность программировать ту часть, которая у вас сейчас есть в области OpenMP, как ядро CUDA.

Функция table_kernel , которая обращается к большой матрице, матрица слишком большая, чтобы храниться в памяти моей видеокарты, поэтому файл останется в ОЗУ. Это проблема? CUDA может легко получить доступ к файлам в ОЗУ? Или это невозможно сделать, и все файлы, необходимые для хранения внутри видеокарты?

Поскольку вы получаете к ней доступ только за пределами области OpenMP, если вы используете ядро CUDA только для работы, которую вы в настоящее время выполняете с OpenMP, не должно быть необходимости в доступе table_kernel с GPU, и поэтому это не должно быть проблемой. Если вы попытаетесь добавить дополнительные циклы для распараллеливания на графическом процессоре, это может стать проблемой. Поскольку доступ был бы относительно редким (по сравнению с обработкой, выполняемой во внутренних циклах), если вы хотите продолжить это, вы могли бы попробовать сделать table_kernel данные доступными для GPU через cudaHostAlloc — в основном отображение памяти хоста в адресном пространстве GPU. Обычно это представляет значительную угрозу для производительности, но если вы обращаетесь к ней нечасто, как упоминалось, это может быть или не быть серьезной проблемой с производительностью.

Обратите внимание, что вы не сможете использовать или получать доступ std::vector к коду устройства, поэтому эти типы контейнеров данных, вероятно, должны быть реализованы как обычные double массивы.

Комментарии:

1. Спасибо, я создам отдельную функцию с тремя циклами и запрограммирую только эту функцию для запуска в GPU. В настоящее время я читаю страницу разработчика NVIDIA и зону разработчика, вы рекомендуете другой материал?

2. Если вам нужно 5-минутное введение в CUDA, вот это . Документация по CUDA находится здесь . Руководство по программированию там довольно полное. Здесь приведена более длительная и упорядоченная обработка программирования CUDA.