为啥这个 CUDA 示例内核有一个 for 循环?

Posted

技术标签:

【中文标题】为啥这个 CUDA 示例内核有一个 for 循环?【英文标题】:Why does this CUDA example kernel have a for loop?为什么这个 CUDA 示例内核有一个 for 循环? 【发布时间】:2013-09-26 08:00:37 【问题描述】:

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

【问题讨论】:

【参考方案1】:

您的版本基本上是当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 的向量上,则一半的向量不会被处理!

不管调用者分配多少线程,官方示例都可以工作,整个向量都会被处理。

【讨论】:

以上是关于为啥这个 CUDA 示例内核有一个 for 循环?的主要内容,如果未能解决你的问题,请参考以下文章

cuda内核for循环中的Break语句给出了问题

GPU 中的并行性 - CUDA / OpenCL

Cuda for 循环疑问

为啥允许我运行块数超过 GPU 的 CUDA 核心数的 CUDA 内核?

为啥 ALSA 示例使用循环播放/捕获?

CUDA:为啥会有大量的 GPU 空闲时间?