优化非常简单的图像处理内核

时间:2015-12-09 00:31:09

标签: cuda

我希望有人能帮助我。我已经在CUDA中弄湿了脚,写了一个简单的内核来否定图像。它的工作非常出色,我很满意。

我想我的愚蠢问题是......无论如何我可以优化这个内核吗?我尝试使用共享内存,但像素数为19224000。

我试图做__shared__ int sharedMem[19224000],这根本就没有运行。我有点迷失在这里,正如CUDA程序员可能会说的那样。

这是我的内核:

__global__ void cuda_negate_image(int * new_array, int * old_array, int rows, int cols){

    int tIdx = threadIdx.x;
    int i = blockDim.x * blockIdx.x + threadIdx.x;
    int n = rows * cols;

   if (i < n)
        new_array[i] = -(old_array[i]) + 255;

}

任何帮助都会很棒!

1 个答案:

答案 0 :(得分:4)

这里的优化空间不大。对于简单的内存绑定操作,通常有四个黄金规则:

  1. 合并内存读写
  2. 使用合并内存访问时最大化每个内存事务的字节数
  3. 使用适当的编译器启发式方法确保发出的代码是最佳的
  4. 在可行的情况下,通过让每个线程处理多个输入来分摊线程调度和设置开销。 (请注意,这需要采用不同的方法来执行网格参数选择,即使用设备的大小,而不是可用工作的总量)
  5. 将这些原则应用于您的内核,我得到类似的结果:

    __device__ __forceinline__ void negate(int &in, int &out)
    {
       out = 255 - in;
    }
    __device__ __forceinline__ void negate(int2 &in, int2 & out)
    {
       negate(in.x, out.x);
       negate(in.y, out.y);
    }
    __device__ __forceinline__ void negate(int4 &in, int4 & out)
    {
       negate(in.x, out.x);
       negate(in.y, out.y);
       negate(in.z, out.z);
       negate(in.w, out.w);
    }
    template<typename T>
    __global__ void cuda_negate_image(T * __restrict__ new_array, T * __restrict__ old_array, int n)
    {
    
       int i = blockDim.x * blockIdx.x + threadIdx.x;
       int stride = blockDim.x * gridDim.x;
    
       T oldval, newval;
       for(; i < n; i += stride) {
          oldval = old_array[i];
          negate(oldval, newval);
          new_array[i] = newval;
       }
    }
    
    template __global__ void cuda_negate_image<int>(int * __restrict__ new_array, int * __restrict__ old_array, int n);
    template __global__ void cuda_negate_image<int2>(int2 * __restrict__ new_array, int2 * __restrict__ old_array, int n);
    template __global__ void cuda_negate_image<int4>(int4 * __restrict__ new_array, int4 * __restrict__ old_array, int n);
    

    只有对目标硬件进行基准测试才能告诉您哪个版本的代码最快,以及这是否值得打扰。