【问题标题】:how to apply atomicAdd to each of element of an array in CUDA?如何将 atomicAdd 应用于 CUDA 中数组的每个元素?
【发布时间】:2014-02-03 04:11:56
【问题描述】:

我有一个来自CUDA 示例的代码到 atomic 添加单个变量

__global__ void myadd(int *data)
{
  unsigned int x = blockIdx.x;
  unsigned int y = threadIdx.x;
  if ( (x%2==0) && (y%2==1) ) atomicAdd(data,1);
}

int main(void)
{
  int *Hdt;
  Hdt = (int*)malloc(sizeof(int));
  // ... CUDA initialization here
  myadd<<<20, 10>>>(Hdt);
  cudaFree(Hdt);
}

它对我很有用。但是我正在扩展我的代码,所以我想将一个数组而不是一个数字传递给内核

__global__ void myadd(int *data)
{
  unsigned int x = blockIdx.x;
  unsigned int y = threadIdx.x;
  unsigned int z = threadIdx.y;
  if ( (x%2==0) && (y%2==1) && (z>4) ) atomicAdd(data[z],1);
}

int main(void)
{
  int *Hdt;
  Hdt = (int*)malloc(sizeof(20*int));
  // ... CUDA initialization here
  myadd<<<20, dim3(10, 20)>>>(Hdt);
  cudaFree(Hdt);
}

但是它没有编译,错误信息是:

错误:没有重载函数“atomicAdd”的实例与 参数列表参数类型为:(int, int)

【问题讨论】:

  • 本题与CUDA或atomicAdd无关。这是关于了解基本数组和函数在 C++ 中的工作原理。
  • 据我了解,这里不需要 atomicAdd,因为每个线程都访问不同的内存位置(data[z] 中的 z)——它们不可能同时写入同一个内存位置。跨度>

标签: c++ cuda


【解决方案1】:

替换:

atomicAdd(data[z],1);

atomicAdd(&data[z],1);

如果您仔细观察,在第一种情况下,您将指针作为 atomicAdd() 的第一个参数。

【讨论】:

  • 非常感谢。是的,这是解决问题的方法。但我有一个关于网格数和线程数的问题。在第一个代码中,如果我将内核运行为 myadd>>(Hdt);它运行没有任何问题。但是如果我使用第二个版本 myadd>>(Hdt);返回的所有数据都是零。是因为线程数的限制吗?如何检查我的设备 (Telsa C2075) 支持多少个网格、块和线程?
  • 您确实应该在每次调用 CUDA api 后检查错误。 cudaGetErrorString(cudaGetLastError()) 给你那种错误。对于块大小,您可以查询 cudaGetDeviceProperties()。请注意,您应该真正阅读有关块大小到底是什么以及它与硬件的关系的基本教程。
  • 查看 cudaGetDeviceProperties(&deviceProp, devID);在您的 cuda 设备上查找网格、块、内存支持
猜你喜欢
  • 1970-01-01
  • 2021-05-25
  • 2012-01-24
  • 1970-01-01
  • 2022-12-11
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
相关资源
最近更新 更多