我正在与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;
}
Run Code Online (Sandbox Code Playgroud)
输出是
count: 0
count: 0
Run Code Online (Sandbox Code Playgroud)
有什么问题?
提前致谢!
你应该传递cuda_count
给你的内核函数.除此之外,所有线程都试图增加相同的内存位置.其效果尚未明确定义(至少一次写入会成功,但不止一次可以).
您需要通过仅让一个线程执行工作来防止这种情况:
__global__ void inc(int *foo) {
if (blockIdx.x == 0 && threadIdx.x == 0)
++*foo;
}
Run Code Online (Sandbox Code Playgroud)
(另)
我找到了解决方案.我只需要使用原子函数,即在不受其他线程干扰的情况下执行的函数.换句话说,在操作完成之前,没有其他线程可以访问特定地址.
码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
输出:
count: 0
count: 2500
Run Code Online (Sandbox Code Playgroud)
感谢您让我意识到我提交的错误.