【问题标题】:Cuda Memory shared in every threads每个线程共享的 Cuda 内存
【发布时间】:2011-12-31 12:40:12
【问题描述】:

我今天开始使用 CUDA 进行冒险。我正在尝试在所有线程之间共享一个 unsigned int 。所有线程都会修改这个值。我使用 cudaMemcpy 将此值复制到设备。但是,最后当计算完成时,我收到这个值等于 0。

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

编辑:

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

但是,如果您愿意...我创建了包含一些值(无符号整数)的向量。我试图做一些事情,比如搜索大于给定共享值的值,但是当向量中的值更大时,我将向量元素加 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;
}

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

【问题讨论】:

  • 这里没有足够的细节来真正肯定地说,但是并发写入通常被认为是一件坏事。
  • 这看起来像是错误的设计。您希望 CUDA 线程并行工作,因此它们通常不需要访问一块联合内存。
  • 想想你说的和你写的代码。当从数组中读取的值大于共享值时,您希望将 1 添加到共享值。您正在做的是将 1 添加到从数组中读取的值,然后将其分配给共享值。是否每个线程都写入同一个地方,即使您有原子操作,每个线程也只会覆盖以前的值,而您将获得的值将是最后一个运行的线程写入的值。没有原子,你只会得到一个未定义的值,也不是你想做的。
  • Nvm,我在做什么。我的问题一般是如何为每个线程使用全局共享内存。

标签: c++ cuda


【解决方案1】:

编辑 - 删除错误

虽然理想情况下您不想这样做 - 除非您可以确定所有线程都将花费大约相同的时间请参阅Cuda thread tutorial

【讨论】:

  • __ syncthreads() 不适用于块间同步(由“每个线程”暗示)。他说的是全局内存中的共享值,而不是__共享__内存。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    阅读你不需要任何特别的东西。你所做的工作,在 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);
    }
    

    【讨论】:

    • 好的,所以您的解决方案似乎没问题。如果我想赋值,那么我可以简单地使用 atomicExch(b, a[idx]+1) 吗?因为我认为它应该在那里......
    • 是的,它在那里,编程指南中的 B.11.1.3 项。
    猜你喜欢
    • 2011-06-29
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 2012-04-27
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多