Недавно я начал заниматься численными вычислениями и решать математические задачи численно, программируя на 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 легко получить доступ к файлам в оперативной памяти? Или это нельзя сделать и все файлы нужно хранить внутри видеокарты?