【问题标题】:Beginner CUDA - Simple var increment not working初学者 CUDA - 简单的 var 增量不起作用
【发布时间】:2010-12-10 12:12:47
【问题描述】:

我正在使用 CUDA 开展一个项目。为了掌握它,我有以下代码。

#include <iostream>

using namespace std;

__global__ void inc(int *foo) {
  ++(*foo);
}

int main() {
  int count = 0, *cuda_count;
  cudaMalloc((void**)&cuda_count, sizeof(int));
  cudaMemcpy(cuda_count, &count, sizeof(int), cudaMemcpyHostToDevice);
  cout << "count: " << count << '\n';
  inc <<< 100, 25 >>> (&count);
  cudaMemcpy(&count, cuda_count, sizeof(int), cudaMemcpyDeviceToHost);
  cudaFree(cuda_count);
  cout << "count: " << count << '\n';
  return 0;
}

输出是

count: 0
count: 0

有什么问题?

提前致谢!

【问题讨论】:

  • 您可能应该完成编程指南中的一些示例。您的语法与编程指南中建议的有出入。

标签: c++ cuda


【解决方案1】:

您应该将cuda_count 传递给您的内核函数。除此之外,您所有的线程都试图增加相同的内存位置。其效果没有明确定义(至少一次写入会成功,但不止一次可以)。

您需要通过只让一个线程执行工作来防止这种情况:

__global__ void inc(int *foo) {
  if (blockIdx.x == 0 && threadIdx.x == 0)
    ++*foo;
}

(未经测试)

【讨论】:

  • 我的失败。然而,输出仍然是错误的。它给了我 1 而不是预期的 2500。
  • @Renato:这不是 CUDA 的工作方式。请参阅我更新的答案:从不同线程写入相同的内存位置只是未定义的。你想要的是一个所谓的收集操作。实现这一点并非易事。
  • Konrad 的修复确保只有带有threadIdx.x == 0 的线程会尝试增加变量,但由于您要启动许多块,您将拥有许多具有该索引的线程。试试blockIdx.x == 0 &amp;&amp; threadIdx.x == 0。话虽如此,可能值得查看一些 SDK 示例,以便更清楚地了解这一切是如何工作的......
  • @Tom:谢谢,我已经相应地改变了我的答案。我上次使用 CUDA 已经两年了。
【解决方案2】:

我找到了解决方案。我只需要使用原子函数,即在不受其他线程干扰的情况下执行的函数。 换句话说,在操作完成之前,没有其他线程可以访问特定地址 完成。

代码:

#include <iostream>

using namespace std;

__global__ void inc(int *foo) {
  atomicAdd(foo, 1);
}

int main() {
  int count = 0, *cuda_count;
  cudaMalloc((void**)&cuda_count, sizeof(int));
  cudaMemcpy(cuda_count, &count, sizeof(int), cudaMemcpyHostToDevice);
  cout << "count: " << count << '\n';
  inc <<< 100, 25 >>> (cuda_count);
  cudaMemcpy(&count, cuda_count, sizeof(int), cudaMemcpyDeviceToHost);
  cudaFree(cuda_count);
  cout << "count: " << count << '\n';
  return 0;
}

输出:

count: 0
count: 2500

感谢您让我意识到我所犯的错误。

【讨论】:

    【解决方案3】:

    您的代码的问题是您将指向设备内核的指针传递给计数。不是计数的指针。一个“&”太多了

    这一行

    inc <<< 100, 25 >>> (&count);
    

    应该是

    inc <<< 100, 25 >>> (count);
    

    【讨论】:

      猜你喜欢
      • 2013-04-15
      • 1970-01-01
      • 2021-09-02
      • 2020-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      相关资源
      最近更新 更多