Cuda Memory在每个线程中共享

时间:2011-11-17 16:32:09

标签: c++ cuda

我今天开始了与CUDA的冒险。我试图在所有线程中共享一个unsigned int。所有线程都修改此值。我使用cudaMemcpy将这一个值复制到设备。但是,在计算结束时,我收到的这个值等于0.

也许有几个线程同时写入这个变量? 我不确定我是否应该使用任何信号量或在线程开始写入时锁定此变量。

修改

很难详细说明,因为我的问题一般是如何解决它。实际上我不会编写任何算法,只测试CUDA。

但如果你愿意......我创建了包含一些值的向量(unsigned int)。我尝试做的事情比搜索大于给定共享值的值,但是,当vector的值更大时,我将向向量元素添加1并保存共享值。

看起来像这样:

__global__ void method(unsigned int *a, unsigned int *b, long long unsigned N) {
    int idx = blockIdx.x* blockDim.x+ threadIdx.x;
    if (a[idx]>*b && idx < N) 
        *b = a[idx]+1;
}

正如我所说,它不是有用的代码,仅用于测试,但我想知道该怎么做......

3 个答案:

答案 0 :(得分:1)

如果值在共享内存中,它将只在单个多处理器(即每个线程块)中运行的每个线程本地,而不是每个运行该内核的线程。如果您希望每个线程都写入变量simultanesouly,您肯定需要执行原子操作(如atomicAdd等)。 请注意,这将序列化所有同时写入变量的线程请求。

答案 1 :(得分:1)

“我的问题一般是如何为每个线程使用共享内存全局。”

阅读你不需要任何特别的东西。你做了什么,在Fermi设备上工作得更快,因为它们有缓存,而其他设备则慢。

如果在其他线程更改后读取该值,则无法等待所有线程在读取所需值之前完成其操作,因此可能与您的预期不符。在所有正在运行的线程之间同步全局内存中的值的唯一方法是使用不同的内核。在您更改要在内核完成的所有线程之间共享的值之后,您将启动一个可以使用共享值的新线程。

要使每个线程写入相同的内存位置,必须使用原子操作,但请记住,应将原子操作保持在最低限度,因为这有效地序列化了执行。

要了解可用的原子函数,请阅读CUDA C编程指南available here的B.11节。

你问的是:

__global__ void method(unsigned int *a, unsigned int *b, long long unsigned N) {
    int idx = blockIdx.x* blockDim.x+ threadIdx.x;
    if (a[idx]>*b && idx < N) 
        //*b = a[idx]+1;
        atomicAdd(b, a[idx]+1);
}

答案 2 :(得分:-1)

编辑 - 删除错误

虽然理想情况下你不想这样做 - 除非你能确定所有的线程大约需要花费同样的时间才能看到Cuda thread tutorial