我在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];
}
答案 0 :(得分:1)
此设置无效;你正在有效地尝试序列化你的块,正如他的评论中提到的那样,它不起作用。来自CUDA编程指南:
“线程块需要独立执行:必须能够以任何顺序,并行或串行执行它们。这种独立性要求允许线程块以任意顺序在任意数量的核心上进行调度......” http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#thread-hierarchy
如果可能启动单独的内核(例如,在第一个内核中执行块0计算,在第二个内核中执行块1等),尝试强制执行第一个内核的结果,然后再读取他们在下一个内核中。已经完成了一些有块间同步的工作,但是你不会从中获得很多好处,因为你需要序列化你的块。
编辑:我还应该指出,块调度没有记录,并且可能随时发生变化,因此任何块间同步都将是不可移植的,并且可能会破坏驱动程序或CUDA工具包更新。