Одним из способов решения этой проблемы является отображение куба в виде набора Z слайдов.Координаты X, Y относятся к ширине и высоте изображения, а координата Z - к каждому слайду в измерении Z.Каждый поток будет перебирать координату Z, чтобы накапливать значения.
Имея это в виду, сконфигурируйте ядро для запуска блока из потоков 16x16 и сетки из блоков, достаточных для обработки ширины и высоты изображения (Я предполагаю, что изображение в оттенках серого с 1 байтом на пиксель):
#define THREADS 16
// kernel configuration
dim3 dimBlock = dim3 ( THREADS, THREADS, 1 );
dim3 dimGrid = dim3 ( WIDTH / THREADS, HEIGHT / THREADS );
// call the kernel
kernel<<<dimGrid, dimBlock>>>(i_data, o_Data, WIDTH, HEIGHT, DEPTH);
Если вы знаете, как индексировать двумерный массив, цикл по измерению Z также будет четким
__global__ void kernel(unsigned char* i_data, unsigned char* o_data, int WIDTH, int HEIGHT, int DEPTH)
{
// in your kernel map from threadIdx/BlockIdx to pixel position
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
// calculate the global index of a pixel into the image array
// this global index is to the first slide of the cube
int idx = x + y * WIDTH;
// partial results
int r = 0;
// iterate in the Z dimension
for (int z = 0; z < DEPTH; ++z)
{
// WIDTH * HEIGHT is the offset of one slide
int idx_z = z * WIDTH*HEIGHT + idx;
r += i_data[ idx_z ];
}
// o_data is a 2D array, so you can use the global index idx
o_data[ idx ] = r;
}
Это наивная реализация.Чтобы максимизировать пропускную способность памяти, данные должны быть правильно выровнены.