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

cuda atomicAdd示例无法生成正确的输出,cuda,Cuda,编写以下代码的目的是将100个元素的浮点数组增加10倍。在输出中,我希望每个元素的值为10.0f的100元素数组。相反,我得到的是随机值。你能指出我的错误吗 __global__ void testAdd(float *a) { float temp; for (int i = 0; i < 100 ; i++) { a[i] = atomicAdd(&a[i], 1.0f); } } void cuTestAtomicAdd(fl

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

__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);
}
\uuuuu全局\uuuuuu无效测试添加(浮点*a)
{
浮子温度;
对于(int i=0;i<100;i++)
{
a[i]=原子加法(&a[i],1.0f);
}
}
void cuTestAtomicAdd(浮动*a)
{
d(a);
}

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

这不是我们执行
atomicAdd
操作的方式

就这样做吧:

atomicAdd(&a[i], 1.0f);
并且相关变量(
a[i]
)将被更新

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

这样做:

a[i] = atomicAdd(&a[i], 1.0f);
将更新变量
a[i]
,然后(非原子地)将旧值分配给变量
a[i]
。这几乎肯定不是你想要的

阅读:

该函数返回old

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

#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;
}
#包括
__全局无效测试DD(浮动*a)
{
对于(int i=0;i<100;i++)
{
原子加法(&a[i],1.0f);
}
}
void cuTestAtomicAdd(浮动*a)
{
d(a);
}
int main(){
浮点*d_数据,*h_数据;
h_数据=(浮动*)malloc(100*sizeof(浮动));
Cudamaloc((无效**)和d_数据,100*sizeof(浮动));
cudaMemset(d_数据,0,100*sizeof(float));
cuTestAtomicAdd(d_数据);
cudaMemcpy(h_数据,d_数据,100*sizeof(float),cudaMemcpyDeviceToHost);
对于(int i=0;i<100;i++)
如果(h_数据[i]!=10.0f){printf(“在%d处不匹配,是%f,应该是%f\n”,i,h_数据[i],10.0f);返回1;}
printf(“成功”\n);
返回0;
}

<代码> >我向您保证,“A”被正确分配为100个元素长,并为所有元素初始化为0值。为了避免竞争条件,在C++中,每次读取或写入内存时,都会使用互斥。什么是Cuda的等价物?另外,我在GTX 780 Ti上运行这个程序,我认为它应该有足够高的计算能力来支持原子。我正在使用VisualStudio2010。我已将所有.cpp和cu文件(设备\代码生成)的属性从前面的compute_10、sm_10更改为compute_35、sm_35。