我一直在尝试弄清楚如何制作一个简单的内核,以计算二维矩阵中值的平均值,但是我在思考过程中遇到了一些问题。
根据我的deviceQuery输出,我的GPU有16MP,32cores/mp,最大块数为1024x1024x64,每个块最大线程数为1024。
因此,我正在处理一些大型图像。可能是5000px x 3500px或类似的大小。我的一个内核正在对图像中所有像素的某些值取平均值。
现有代码将图像存储为2D数组[rows][cols]。因此,在C中,该内核看起来像您期望的那样,通过循环遍历行和列,并在中间进行计算。
那么,我如何在CUDA中设置这段代码的维度计算部分呢?我已经查看了SDK中的减少代码,但那是针对单维数组的。它没有提到如何为2D情况设置块和线程的数量。
我认为我实际上需要这样设置,这就是我想让别人加入并帮助我的地方:
根据我的deviceQuery输出,我的GPU有16MP,32cores/mp,最大块数为1024x1024x64,每个块最大线程数为1024。
因此,我正在处理一些大型图像。可能是5000px x 3500px或类似的大小。我的一个内核正在对图像中所有像素的某些值取平均值。
现有代码将图像存储为2D数组[rows][cols]。因此,在C中,该内核看起来像您期望的那样,通过循环遍历行和列,并在中间进行计算。
那么,我如何在CUDA中设置这段代码的维度计算部分呢?我已经查看了SDK中的减少代码,但那是针对单维数组的。它没有提到如何为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];
}
}
}
使用cudaMallocPitch函数声明二维数组的方式与在C语言中使用malloc函数类似,但是没有提到如何在自己的内核中访问该数组。我猜在我的代码中,我将使用cudaMallocPitch调用,然后执行memcpy将数据传输到设备上的二维数组中?
如果有任何提示,请告诉我!谢谢!