Как эффективно вычислять функции в трехмерной сетке с помощью распараллеливания графического процессора?C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Как эффективно вычислять функции в трехмерной сетке с помощью распараллеливания графического процессора?

Сообщение Anonymous »

Я работаю над проектом, в котором мне нужно вычислить функцию в каждой точке 3D-сетки. Изначально я использовал вложенный цикл для перебора всех точек и выполнения вычислений. Этот подход был многопоточным, в котором работа распределялась по оси Z, где каждый поток обрабатывал часть сетки:

Код: Выделить всё

// Iterate over the Z-axis of the 3D grid
for (int z = 0; z < dim[2]; ++z) {
// Iterate over the Y-axis of the 3D grid
for (int y = 0; y < dim[1]; ++y) {
// Iterate over the X-axis of the 3D grid
for (int x = 0; x < dim[0]; ++x) {
// Create a 3D point (pt) to represent the current position in the grid
vec3 pt;
// Calculate the X coordinate of the point as a normalized value between 0 and 1
pt[0] = (static_cast(x) / static_cast(dim[0]));
// Calculate the Y coordinate of the point as a normalized value between 0 and 1
pt[1] = (static_cast(y) / static_cast(dim[1]));
// Calculate the Z coordinate of the point as a normalized value between 0 and 1
pt[2] = (static_cast(z) / static_cast(dim[2]));
// Compute the value of the function at the current point
double val = computeFunction(pt);
// Store the computed value in the results vector
results.push_back(val);
}
}
}
Теперь, конечно, функцию ComputeFunction() необходимо перенести на CUDA, но я хочу сосредоточиться на логике эффективного разделения трехмерной сетки точек на блоки точек в параллельно.
Изображение

Я думал об этой реализации, которая возвращает одномерный массив:

Код: Выделить всё

__device__ double computeFunction(double x, double y, double z) {
return x * y * z; // Example function
}

__global__ void compute3dGrid(double* results, int dimX, int dimY, int dimZ) {
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
int z = blockIdx.z * blockDim.z + threadIdx.z;

if (x < dimX && y < dimY && z < dimZ) {
double pt_x = static_cast(x) / static_cast(dimX);
double pt_y = static_cast(y) / static_cast(dimY);
double pt_z = static_cast(z) / static_cast(dimZ);

double val = computeFunction(pt_x, pt_y, pt_z);

int idx = z * dimX * dimY + y * dimX + x;
results[idx] = val;
}
}

void launchGridComputation(double* h_results, int dimX, int dimY, int dimZ) {
double* d_results;
size_t size = dimX * dimY * dimZ * sizeof(double);

cudaMalloc(&d_results, size);

dim3 blockSize(8, 8, 8);
dim3 gridSize(
(dimX + blockSize.x - 1) / blockSize.x,
(dimY + blockSize.y - 1) / blockSize.y,
(dimZ + blockSize.z - 1) / blockSize.z
);

compute3dGrid(d_results, dimX, dimY, dimZ);

cudaMemcpy(h_results, d_results, size, cudaMemcpyDeviceToHost);

cudaFree(d_results);
}
В конечном итоге эта проблема может потребовать метода проб и ошибок для оптимизации размеров блоков?
Есть ли лучший способ сделать это?< /strong>

Подробнее здесь: https://stackoverflow.com/questions/787 ... lelization
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»