使用cuda atomicAdd来移植这段代码

时间:2016-02-16 08:50:38

标签: cuda

这是我的顺序代码:

float foo(float* in1, float* in2, float in3, unsigned int size) {
    float tmp = 0.f;
        for (int i = 0; i<size; i++)
          if(in2[i]>0)tmp += (in1[i]/in3 - (in2[i] /in3)*(in2[i] /in3));
    return tmp;
}

这是我将其移植到CUDA的努力:

__global__ void kernel_foo(float* tmp, const float* in1, const float* 
                           in2, float in3,  unsigned int size) {
    unsigned int i = blockDim.x * blockIdx.x + threadIdx.x;
    if (i < size) {
        if(in2[i]>0){
        atomicAdd(tmp, in1[i]/in3 - (in2[i] /in3)*(in2[i] /in3));
        }
    }
}

void launch_kernel_foo(float* tmp, const float* in1, const float* in2,
                       float in3,  unsigned int size) {
  kernel_foo<<<(size+255)/256,256>>>(tmp, in1, in2, in3, size);
}

但它无法生成正确的结果。谁能告诉我哪里出错了?

1 个答案:

答案 0 :(得分:3)

导致错误结果的原因是在启动内核之前尚未初始化输出变量tmp。在执行计算之前,应将其初始化为 0 。它可以如下完成。

void launch_kernel_foo(float* tmp, const float* in1, const float* in2,
                       float in3,  unsigned int size) {
  cudaMemset(tmp, 0, sizeof(float));
  kernel_foo<<<(size+255)/256,256>>>(tmp, in1, in2, in3, size);
} 

强烈建议您按照this post中的说明在代码中添加CUDA错误检查。