Der*_*rek 6 c++ cuda gpu gpgpu
我一直在试图弄清楚如何制作我认为是一个简单的内核来获取2d矩阵中的值的平均值,但是我有一些问题让我的思维过程直接进行.
根据我的deviceQuery输出,我的GPU有16MP,32cores/mp,块最大为1024x1024x64,我有一个最大线程/块= 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);
Run Code Online (Sandbox Code Playgroud)
这似乎对设置有意义吗?
然后在内核中,要处理特定的行或列,我必须使用
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];
}
}
}
Run Code Online (Sandbox Code Playgroud)
这看起来类似于你在C中使用malloc来声明一个2D数组,但它没有提到在你自己的内核中访问该数组.我想在我的代码中,我将使用cudaMallocPitch调用,然后执行memcpy将我的数据导入设备上的2D数组?
任何提示赞赏!谢谢!
下面是我自己的代码中的一个简短的片段,其中包含一个简单的内核。浮点指针都是设备指针。希望这有帮助。
定义和帮助函数:
#define BLOCK_SIZE 16
int iDivUp(int a, int b){
return (a % b != 0) ? (a / b + 1) : (a / b);
}
Run Code Online (Sandbox Code Playgroud)
块大小计算:
dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);
dim3 dimGridProj(iDivUp(width,BLOCK_SIZE), iDivUp(height,BLOCK_SIZE));
Run Code Online (Sandbox Code Playgroud)
主持人电话:
calc_residual<<<dimGridProj, dimBlock>>>(d_image1, d_proj1, d_raynorm1, d_resid1, width, height);
Run Code Online (Sandbox Code Playgroud)
核心:
__global__ void calc_residual(float *d_imagep, float *d_projp, float *d_raysump, float *d_residualp, int width, int height)
{
int iy = blockDim.y * blockIdx.y + threadIdx.y;
if (iy >= height) {
return;
}
int ix = blockDim.x * blockIdx.x + threadIdx.x;
if (ix >= width) {
return;
}
int idx = iy * width + ix;
float raysumv = d_raysump[idx];
if (raysumv > 0.001) {
d_residualp[idx] = (d_projp[idx]-d_imagep[idx])/raysumv;
}
else{
d_residualp[idx] = 0;
}
}
Run Code Online (Sandbox Code Playgroud)