C++ Cuda内存在每个线程中共享

C++ Cuda内存在每个线程中共享,c++,cuda,C++,Cuda,今天我和库达开始了我的冒险。我试图在所有线程之间共享一个无符号int。所有线程都修改此值。我使用cudaMemcpy将这个值复制到设备上。但是,在计算结束时,我得到这个值等于0 可能有多个线程同时写入此变量? 我不确定在线程开始写入时是否应该使用任何信号量或锁定此变量 编辑: 很难说得更详细,因为我的问题通常是如何解决它。实际上我没有写任何算法,只是测试CUDA 但是如果你愿意。。。我创建了包含一些值(无符号int)的向量。我试图搜索比给定共享值大的值,但是,当vector中的值更大时,我将向v

今天我和库达开始了我的冒险。我试图在所有线程之间共享一个无符号int。所有线程都修改此值。我使用cudaMemcpy将这个值复制到设备上。但是,在计算结束时,我得到这个值等于0

可能有多个线程同时写入此变量? 我不确定在线程开始写入时是否应该使用任何信号量或锁定此变量

编辑:

很难说得更详细,因为我的问题通常是如何解决它。实际上我没有写任何算法,只是测试CUDA

但是如果你愿意。。。我创建了包含一些值(无符号int)的向量。我试图搜索比给定共享值大的值,但是,当vector中的值更大时,我将向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;
}
\uuuuu全局\uuuuu无效方法(无符号int*a、无符号int*b、长-长无符号N){
int idx=blockIdx.x*blockDim.x+threadIdx.x;
if(a[idx]>*b&&idx
正如我所说,它不是有用的代码,只是用于测试,但我想知道如何做…

编辑-删除错误

虽然理想情况下您不想这样做-除非您可以确保所有线程都将占用大约相同的时间-请参见

编辑-删除错误


虽然理想情况下您不希望这样做,但除非您能够确保所有线程都将占用大约相同的时间,请参见

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

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

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

阅读不需要什么特别的东西。您所做的工作在费米设备上运行得更快,因为它们有缓存,而在其他设备上运行得更慢

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

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

要了解可用的原子函数,请阅读CUDA C编程指南的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);
}
\uuuuu全局\uuuuu无效方法(无符号int*a、无符号int*b、长-长无符号N){
int idx=blockIdx.x*blockDim.x+threadIdx.x;
if(a[idx]>*b&&idx
“我的问题通常是如何为每个线程使用全局共享内存。”

阅读不需要什么特别的东西。您所做的工作在费米设备上运行得更快,因为它们有缓存,而在其他设备上运行得更慢

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

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

要了解可用的原子函数,请阅读CUDA C编程指南的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);
}
\uuuuu全局\uuuuu无效方法(无符号int*a、无符号int*b、长-长无符号N){
int idx=blockIdx.x*blockDim.x+threadIdx.x;
if(a[idx]>*b&&idx
这里没有足够的细节来确定,但并发写入通常被认为是一件坏事。这看起来是错误的设计。您希望CUDA线程能够并行工作,因此它们通常不需要访问一段联合内存。当从数组读取的值大于共享值时,您希望向共享值添加1。您要做的是将1添加到从数组读取的值中,然后将其分配给共享值。如果每个线程都写入同一个位置,即使您进行了原子操作,每个线程都会覆盖上一个值,并且您将获得的值将是运行的最后一个线程写入的值。没有原子,你只能得到一个未定义的值,而这两个值都不是你想要做的。我的问题是如何为每个线程使用全局共享内存。这里没有足够的细节来确定,但并发写入通常是错误的