2016-12-02 74 views
0

我目前正在处理作为二进制文件读入的图像(二维数组),并且应该是CUDA的512x4096。我的问题是如何处理特定的索引(关于块和线程),当一切都真正存储为一维数组时。作为一个例子,我试图创建一个函数,让每一个细节都向右移动。我的代码是如何使用块和螺纹尺寸来处理2D图像

//CircShift, without scaling 
__global__ void circShift(cufftComplex* input, cufftComplex* output, int numK, int numA) { 
    int w = blockDim.x * blockIdx.x + threadIdx.x; 
    int h = blockDim.y * blockIdx.y + threadIdx.y; 
    if ((h < numA) && (w < numK)) { 
     int idx = h * numK + w; 
     if (w+1<numK) { 
      output[h*numK+w+1].x = input[idx].x; 
      output[h*numK+w+1].y = input[idx].y; 
     } else { 
      output[h*numK].x = input[idx].x; 
      output[h*numK].y = input[idx].y; 
     } 


    } 

} 

我目前的blockdim是(256,64),我的threaddim是(16,8)。

我想知道如果这是正确的方式来实现这样的索引方面的东西。我的w等于列#,我的h等于行号。让我们说我正在使用类似python的东西,并将图像加载为二维数组M.在CUDA中通过h * numK + w进行索引以尝试访问M [h] [w]。

回答

1

你的索引似乎是正确的假设图像矩阵具有行主要排序:w会给你绝对X图像中的坐标(或列数)和h*numK+w相当于y * imageWidth + x这是在访问细胞中常见的成语在CUDA中。只要确保你的整个图像网格覆盖(你只写了512x4096,我假设4096是图像宽度)。

作为旁注,您应该每个线程访问您的cufftComplex元素一次,而不是复制您的operator[]访问代码(也作为重构点)。

+0

感谢您的回复!你能详细说明一下附注吗? – Jason

+0

@Jason当然,我的意思是只读一次'cufftComplex',而不是两次访问'x'和'y'的同一位置。这可能会保证更好的内存合并并避免一些不必要的读数(尽管编译器可能会优化它)。 –

+0

嗯,这是有道理的。谢谢! – Jason