2013-09-26 129 views
2

我一直在看下面的例子来自官方CUDA网站:为什么这个CUDA示例内核有for循环?

http://docs.nvidia.com/cuda/cuda-samples/index.html#simple-cufft

这里下载:http://developer.download.nvidia.com/compute/DevZone/C/Projects/x64/simpleCUFFT.zip

它包含以下内核:

// Complex pointwise multiplication 
static __global__ void ComplexPointwiseMulAndScale(Complex *a, const Complex *b, int size, float scale) 
{ 
    const int numThreads = blockDim.x * gridDim.x; 
    const int threadID = blockIdx.x * blockDim.x + threadIdx.x; 

    for (int i = threadID; i < size; i += numThreads) 
    { 
     a[i] = ComplexScale(ComplexMul(a[i], b[i]), scale); 
    } 
} 

我的问题是,为什么在这里有for循环? CUDA不会同时调用线程数组吗?我删除了线程,用下面的代码替换它,并生成了相同的输出。

// Complex pointwise multiplication 
static __global__ void ComplexPointwiseMulAndScale(Complex *a, const Complex *b, int size, float scale) 
{ 
    const int threadID = blockIdx.x * blockDim.x + threadIdx.x; 

    a[threadID] = ComplexScale(ComplexMul(a[threadID], b[threadID]), scale); 
} 

由于这是CUDA网站上的官方示例,我想我必须缺少一些东西。

回答

5

你的版本基本上是numThreads等于size(但是只有)时发生的情况。

什么官方示例所做的是下面的:假设numThreads等于4(为简单起见,通常这将是更大的),并考虑阵列位置(无论是ab):

a or b     x x x x x x x x 
    thread that works here 0 1 2 3 0 1 2 3 

然后第一个线程将在所有可被4整除的数组位置上工作,等等。

与您的版本的问题是,您的函数的调用者将不得不确保有多少线程size是大。例如,如果您使用1-dim网格调用您的版本,并且gridDim.xblockDim.x都是2,但在长度为8的矢量上,则不会处理一半的矢量!

官方示例无论 - 无论调用者分配给它多少个线程,整个矢量都将被处理。