2010-12-10 39 views
6

我正在与CUDA一起开发项目。为了掌握它,我有以下代码。初学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 

什么问题?

提前致谢!

+0

你应该通过一些在节目指南的例子也许可以工作。您的语法与编程指南中建议的内容不一致。 – Marm0t 2010-12-10 18:10:24

回答

6

我找到了解决办法。我只需要使用一个原子函数,即一个不受其他线程干扰的函数。 换句话说,在操作完成后,没有其他线程可以访问特定地址。

代码:

#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 

谢谢你让我知道我犯下了错误。

8

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

您需要防止由只让一个线程执行的工作:

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

(未经测试)

+0

什么是我的失败。然而,它的输出仍然是错误的。它给了我1而不是预期的2500. – 2010-12-10 12:39:40

+5

@Renato:这不是CUDA的工作原理。看到我更新的答案:它只是未定义从不同的线程写入相同的内存位置。你想要的是一个所谓的收集操作。实现这一点并不重要。 – 2010-12-10 12:41:23

+0

我试过你的快速修复,但输出为2. – 2010-12-10 12:48:37

0

你的代码的问题是你传递给设备内核指针指向count。没有指针可以计数。一个“&”太多

此行

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

应该

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