【问题标题】:Failing to read an array from the global mem CUDA无法从全局内存 CUDA 读取数组
【发布时间】:2013-01-23 15:42:03
【问题描述】:

我正在 CUDA 上实现一个复杂的算法。但是有一个非常奇怪的问题。问题可以概括为:内核会多次重复一系列计算。本次迭代的计算是基于前一次的结果。我在全局内存上使用一个数组在每次迭代中的块之间传递信息。例如有 2 个块,对于每个迭代块 0 将结果保存到全局内存,然后块 1 从全局内存中读取它。但是问题是块 1 无法从全局内存中读取数组。它有时会返回第一次迭代的结果,而不是前一次。

a_e 和 e_a 是全局 mem 上的两个数组,大小为 [2*8]。 d_a_e和d_e_a在共享mem上,大小为[blockDim.x+1][8]。

if(threadIdx.x<8)
{
     //block 0 writes, block 1 reads, this can't work properly
     a_e[blockIdx.x*8+threadIdx.x]=d_a_e[blockDim.x][threadIdx.x];
     if(blockIdx.x>0)
          d_a_e[0][threadIdx.x]=a_e[(blockIdx.x-1)*8+threadIdx.x];

     //block 1 writes, block 0 reads, this can work properly
     e_a[blockIdx.x*8+threadIdx.x]=d_e_a[0][threadIdx.x];
     if(blockIdx.x < gridDim.x-1)
          d_e_a[blockDim.x][threadIdx.x]=e_a[(blockIdx.x+1)*8+threadIdx.x];
}

【问题讨论】:

  • Cuda 不保证第一个 block 会在第二个 block 之前运行,即使这样做也不能保证全局内存一致性。

标签: cuda gpgpu


【解决方案1】:

此设置不起作用;您正在有效地尝试序列化您的块,正如他在评论中提到的那样,这是行不通的。来自 CUDA 编程指南:

“线程块需要独立执行:必须能够以任何顺序并行或串行执行它们。这种独立性要求允许线程块以任意顺序在任意数量的内核上调度......” http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#thread-hierarchy

如果可能启动单独的内核(例如您在第一个内核中执行块 0 计算,在第二个内核中执行块 1 等),您最好的办法是尝试强制执行第一个内核的结果在读取之前完成它们在下一个内核中。已经完成了一些关于块间同步的工作,但您不会从它们中获得太多好处,因为您需要序列化您的块。

编辑:我还应该指出,块调度没有记录在案,并且随时可能更改,因此任何块间同步都将是不可移植的,并且可能会在驱动程序或 CUDA 工具包更新时中断.

【讨论】:

    猜你喜欢
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 2012-06-05
    • 1970-01-01
    • 2016-05-05
    • 2014-07-21
    • 2020-08-17
    • 2013-11-09
    相关资源
    最近更新 更多