0

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

a_e 和 e_a 是全局 mem 上的两个数组,大小为 [2*8]。d_a_e 和 d_e_a 在共享内存上,大小为 [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];
}
4

1 回答 1

1

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

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

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

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

于 2013-01-24T00:09:52.747 回答