【问题标题】:CUDA 2D Convolution kernelCUDA 2D 卷积核
【发布时间】:2012-05-31 09:15:35
【问题描述】:

我是 CUDA 的初学者,我正在尝试实现 Sobel Edge 检测内核。 我正在使用此代码,但它不起作用。 谁能告诉我它有什么问题。我只得到一些 -1 和一些非常大的值。

__global__ void EdgeDetect_Hor(int *gpu_Edge_Hor, int *gpu_P, 
        int *gpu_Hor, int W, int H)
{ 
    int X = threadIdx.x; 
    int Y = threadIdx.y; 

    int sum = 0; 
    int k1, k2; 
    int min1, min2; 

    for (k1 = 0; k1 < 3; k1++) 
        for(k2 = 0; k2 <3;k2++) 
            sum += gpu_Hor[k1*3+k2]*gpu_P[(X-k1)*H+Y-k2]; 

    gpu_Edge_Hor[X*H+Y] = sum/5000;
} 

我这样称呼这个内核:

dim3 dimBlock(W,H);
dim3 dimGrid(1,1);
EdgeDetect_Hor<<<dimGrid, dimBlock>>>(gpu_Edge_Hor, gpu_P, gpu_Hor, W, H);

【问题讨论】:

  • 谢谢我正在处理一个 480x720 帧的视频
  • 您的内核永远不会运行,因为您拥有的块大小是非法的。有关块大小限制,请参阅 Cuda C 编程指南的附录 F。
  • 以后,通过 Linux 上的 cuda-gdb 运行程序,即 cuda 调试器。您实际上不必通过猜测来编码。

标签: cuda convolution


【解决方案1】:

首先,您的问题是您处理 480x720 像素的图像。 CUDA 支持计算能力 2.0 及更高版本的线程块的最大大小为 1024,而之前的线程块大小为 512。所以你不能在一个块中执行这么多线程。 dim3 dimBlock(W,H); 行不正确。你应该把你的线程分成几个块。

另一个问题是 CUDA 以行优先顺序处理数据。所以你应该改变你的内存访问模式。

CUDA 中二维数组的正确内存访问模式是

BaseAddress + width * Y + X

在哪里

unsigned int X = blockIdx.x * blockDim.x + threadIdx.x;
unsigned int Y = blockIdx.y * blockDim.y + threadIdx.y;

【讨论】:

  • 谢谢我做了这些改变:dim3 dimBlock(32,32);昏暗3昏暗网格(19,19);并且还改变了我的寻址模式。现在好多了(我实际上看到了一些东西!)但是有些块有一些垂直的空白条。你知道它可能是什么吗?
  • 您是否检查过您的线程索引是否小于实际图像大小?
  • 我使用 18 个块而不是 19 个块来确保这一点,但输出没有改变,这些条也出现在帧的中间。所以我不认为是这样。
  • 已解决,谢谢。这是dimGrid(23,15);你很有帮助!
猜你喜欢
  • 2012-04-26
  • 2017-12-11
  • 1970-01-01
  • 2018-05-03
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 2016-06-20
  • 2012-03-06
相关资源
最近更新 更多