CUDA减少优化示例

时间:2016-05-17 03:02:43

标签: optimization cuda nvidia reduction

我正在尝试在CUDA Reduction实施优化,并成功完成到第6部分。感谢大家帮助我。为了完全了解CUDA,我还需要完成最终的优化,如幻灯片#31中提到的,称为算法级联。

这个想法基本上是每个线程有512个元素,并在执行缩减之前按顺序将它们相加。

我尝试了一种方法,我的每个线程都从内存中访问连续的512个数字。不幸的是,它的表现最差。我猜想有银行冲突的原因,但仍然没有弄清楚。你们中的任何一个人都可以提出这种行为的原因吗?

我还发布了Nvidia提供的示例代码。

unsigned int tid = threadIdx.x;
unsigned int i = blockIdx.x*(blockSize*2) + threadIdx.x;
unsigned int gridSize = blockSize*2*gridDim.x;
sdata[tid] = 0;
while (i < n) {
    sdata[tid] += g_idata[i] + g_idata[i+blockSize];
    i += gridSize;
}
__syncthreads();

未定义几个参数。我可以推断blockSize等于每个块的线程数。但我无法推断变量'gridSize'的重要性。访问内存的适当方式是什么,以便我们获得更好的性能?这是跨步访问的一个例子吗?

如果您有任何其他问题,请提前感谢您的帮助和评论。

2 个答案:

答案 0 :(得分:1)

假设每个块有blockDim.x = blockSize = 256个线程,并且网格中有gridDim.x = 32个块,并且您希望减少一个大型数组g_idata[8,192,000]

然后你总共有8192个帖子。我们来使用

thread[x][y], x=0..31, y=0..255

代表这些线程。

每个thread[x][y]正在加载

g_idata[iter*512*x+y] and g_idata[iter*512*x+256+y], iter = 0 .. 999

到共享内存sdata

对于每次迭代iter,所有8192 threads[x][y]都会从GPU内存中加载gridSize = 16384个元素。

这是合并的内存访问,它是访问GPU内存的正确方法。

然而,您的方式,每个thread[x]读取data[i*x*512 .. i*(x+1)*512-1], i=0...并不是一个好方法。实际上,它是访问GPU内存的最低效的可能方式。

答案 1 :(得分:0)

这是合并访问的一个例子。最好的gridDim取决于您的硬件。根据每个线程的寄存器和每个块的最大线程数,此值应该是硬件上可用的多处理器数量的乘数。如果你的问题足够大,8倍的多处理器数量对开普勒来说是一个很好的选择,对麦克斯韦来说是16倍。