Я пытался выяснить, как сделать то, что, как я думал, было бы простым ядром для вычисления средних значений в матрице 2d, но у меня возникают некоторые проблемы, связанные с моим мыслительным процессом.выяснить, сколько блоков и потоков для ядра cuda и как их использовать
Согласно моему выпуску deviceQuery, мой GPU имеет 16MP, 32cores/mp, max max - 1024x1024x64, а максимальный поток/block = 1024.
Итак, я работаю над обработкой некоторых больших изображений. Может, 5000px x 3500px или что-то в этом роде. Одно из моих ядер принимает среднее значение некоторых значений во всех пикселях изображения.
Существующий код имеет изображения, хранящиеся в виде 2D-массива [rows] [cols]. Таким образом, ядро в C выглядит так, как вы ожидали бы, с циклом над строками и циклом над cols, с вычислением в середине.
Итак, как мне настроить часть вычисления размера этого кода в CUDA? Я посмотрел на код сокращения внутри SDK, но это для одного массива измерений. В нем нет упоминаний о том, как настроить количество блоков и потоков, если у вас есть soemthing 2D.
Я имею в виду, я бы на самом деле нужно, чтобы настроить его, как это так, и это, где я хотел бы кого-то, чтобы звонить в и помощь:
num_threads=1024;
blocksX = num_cols/sqrt(num_threads);
blocksY = num_rows/sqrt(num_threads);
num_blocks = (num_rows*num_cols)/(blocksX*blocksY);
dim3 dimBlock(blocksX, blocksY, 1);
dim3 dimGrid(num_blocks, 1, 1);
Кажется ли это имеет смысл для установки ?
И затем в ядре, чтобы работать на определенной строке или столбце, я должен был бы использовать
rowidx = (blockIdx.x * blockDim.x) + threadId.x colidx = (blockIdx. y * blockDim.y) + threadId.y
По крайней мере, я думаю, что это будет работать для получения строки и столбца.
Как я мог бы получить доступ к этой конкретной строке r и столбцу c в ядре? В руководстве по программированию CUDA я нашел следующий код:
// Host code int width = 64, height = 64;
float* devPtr; size_t pitch;
cudaMallocPitch(&devPtr, &pitch, width * sizeof(float), height);
MyKernel<<<100, 512>>>(devPtr, pitch, width, height);
// Device code __global__ void MyKernel(float* devPtr, size_t pitch, int width, int height)
{
for (int r = 0; r < height; ++r)
{
float* row = (float*)((char*)devPtr + r * pitch);
for (int c = 0; c < width; ++c)
{
float element = row[c];
}
}
}
который похож на то, как вы будете использовать таНос в C, чтобы объявить 2D массива, но он не имеет никакого упоминания о доступе к массиву в собственном ядре , Думаю, в моем коде я буду использовать этот вызов cudaMallocPitch, а затем выполнить memcpy, чтобы получить мои данные в 2D-массив на устройстве?
Любые советы оценены! Благодаря!
Если я понимаю, что делает iDivUP, вы можете немного упростить логику благодаря целочисленному усечению: return (a + b-1)/b; –