CUDA - 这个循环在做什么

时间:2011-03-16 20:29:03

标签: cuda

喂 我在网站上看过这个示例内核

 __global__ void loop1( int N, float alpha, float* x, float* y ) {
   int i;
   int i0 = blockIdx.x*blockDim.x + threadIdx.x;

   for(i=i0;i<N;i+=blockDim.x*gridDim.x) {
      y[i] = alpha*x[i] + y[i];
    }
}   

在C

中计算此功能
   for(i=0;i<N;i++) {
      y[i] = alpha*x[i] + y[i];
   }

当然内核中的for循环不是必需的吗?你可以y[i0] = alpha*x[i0] + y[i0]完全删除for循环。

我只是好奇为什么它在那里以及它的目的是什么。这假定是内核调用,例如loop1<<<64,256>>>>,因此可能是gridDim.x = 1

3 个答案:

答案 0 :(得分:4)

如果向量的条目多于启动的线程,则需要内核中的for循环。如果可能的话,启动足够的线程当然更有效。

答案 1 :(得分:2)

有趣的内核。内核中的循环是必要的,因为N大于总线程数,即16 384(blockDim.x * gridDim.x),但我认为这样做不是好习惯( CUDA的重点是使用SIMT概念)。根据CUDA编程指南,一个内核最多可以包含65535个线程块。此外,从Compute Capability 2.x(Fermi)开始,每个块最多可包含1024个线程(Fermi之前为512个)。您也可以(如果可能)将代码分成多个(顺序)内核。

答案 2 :(得分:1)

就像我们想要相信CUDA GPU具有无限的执行资源一样,他们却没有,并且高度优化的代码的作者发现展开的for循环(通常具有固定数量的块)可以提供最佳性能。编码很痛苦,但优化的CPU代码也很痛苦。

btw一位评论者提到这段代码会产生合并问题,我不明白为什么。如果基址正确对齐(64B,因为它们是浮点数),则此代码的所有内存事务都将被合并,前提是线程/块也可以被64整除。