如何使用块和线程维度来处理2D图像

时间:2016-12-02 19:08:38

标签: parallel-processing cuda

我目前正在处理以二进制文件形式读取的图像(2D数组),并且应该是带有CUDA的512x4096。我的问题是当一切都真正存储为一维数组时,我如何处理特定的索引(关于块和线程)。作为一个例子,我试图创建一个将每个东西向右旋转的函数。我的代码是

//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的东西并将图像加载为2D数组M.通过h * numK + w在CUDA中进行索引,以便尝试访问M [h] [w]。

1 个答案:

答案 0 :(得分:1)

假设图像矩阵具有行主排序,您的索引似乎是正确的:w将为您提供图像(或列号)中的绝对x坐标和h*numK+w相当于y * imageWidth + x,这是访问CUDA中的单元格的常用习惯用法。只需确保覆盖整个图像网格(您刚刚编写了512x4096,我假设4096是图像宽度)。

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