cuda atomicAdd示例无法产生正确的输出

Gum*_*jr. 1 cuda

编写以下代码的目的是将100个元素的浮点数组递增1到10倍.在输出中,我期望每个元素的100元素值为10.0f值.相反,我得到随机值.你能指出我的错误吗?

__global__  void testAdd(float *a)
{
    float temp;
    for (int i = 0; i < 100 ; i++)
    {
        a[i] = atomicAdd(&a[i], 1.0f);
    }
}
void cuTestAtomicAdd(float *a)
{
    testAdd<<<1, 10>>>(a);
}
Run Code Online (Sandbox Code Playgroud)

我的目标是了解原子操作的工作原理,以便将它们应用到其他地方.

Rob*_*lla 13

这不是我们atomicAdd做手术的方式.

就这样做:

atomicAdd(&a[i], 1.0f);
Run Code Online (Sandbox Code Playgroud)

并且a[i]将更新问题()中的变量.

原子函数的返回值通常是原子更新之前变量中的值.

这样做:

a[i] = atomicAdd(&a[i], 1.0f);
Run Code Online (Sandbox Code Playgroud)

将更新变量a[i],然后(非原子地)将值分配给变量a[i].这几乎肯定不是你想要的.

阅读文档:

该函数返回旧的.

以下完整代码演示了正确的用法:

#include <iostream>

__global__  void testAdd(float *a)
{
    for (int i = 0; i < 100 ; i++)
    {
        atomicAdd(&a[i], 1.0f);
    }
}
void cuTestAtomicAdd(float *a)
{
    testAdd<<<1, 10>>>(a);
}

int main(){

  float *d_data, *h_data;
  h_data=(float *) malloc(100*sizeof(float));
  cudaMalloc((void **)&d_data, 100*sizeof(float));
  cudaMemset(d_data, 0, 100*sizeof(float));
  cuTestAtomicAdd(d_data);
  cudaMemcpy(h_data, d_data, 100*sizeof(float), cudaMemcpyDeviceToHost);
  for (int i = 0; i < 100; i++)
    if (h_data[i] != 10.0f) {printf("mismatch at %d, was %f, should be %f\n", i, h_data[i], 10.0f); return 1;}
  printf("Success\n");
  return 0;
}
Run Code Online (Sandbox Code Playgroud)