2

我一直在 CUDA 官方网站上查看以下示例:

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 网站上的官方示例,我想我一定遗漏了一些东西。

4

1 回答 1

5

您的版本基本上numThreads是等于size(但在那时)时发生的情况。

官方示例的作用如下:假设numThreads等于 4(为简单起见,通常它会大得多),并考虑数组位置(forab):

  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.x都是blockDim.x2,但在长度为 8 的向量上,则一半的向量不会被处理!

官方示例无论如何都有效 - 无论调用者分配多少线程,都会处理整个向量。

于 2013-09-26T08:08:36.207 回答