2

我正在研究 GPU 编程,想了解更多关于 CUDA 的信息。我已经阅读了很多关于它的内容(来自 Wikipedia、Nvidia 和其他参考资料),但我仍然有一些问题:

  1. 以下对架构的描述是否准确?:GPU 有多个处理器,每个多处理器都有流处理器,每个流处理器可以同时运行线程块。

  2. 所有参考资料都指出,在一个块内创建的最小线程数是 32……这是为什么呢?

  3. 我有一个 ATI Radeon 视频卡。我能够在没有仿真模式的情况下编译一个简单的 CUDA 程序!!。我以为我只能在支持的 Nvidia VGA 上编译和运行 CUDA 程序。有人可以解释一下吗?

4

3 回答 3

6

1 - 这适用于 NVIDIA gpus。

2 - 这是硬件设计的一个约束。

3 - 编译在 CPU 上完成,因此您可以像在 x86 上为 PPC 交叉编译一样编译程序。

如果你想在 ATI 卡上运行 gpu 程序,我建议你看看 OpenCL 或 AMD Stream。

于 2009-12-30T16:43:19.723 回答
6

一个 CUDA 线程非常轻量级,可以在很少的惩罚下调度/停止。这与 CPU 线程不同,它有很多开销来切换执行和退出执行。因此,CPU 非常适合任务并行,而 GPU 则擅长数据并行。

  1. 在 CUDA 架构中,(NVIDIA)GPU 具有“流式多处理器”(SM),每个处理器都将执行一个线程块。每个 SM 都有一组流处理器 (SP),每个流处理器将在任何给定时刻(周期)为一个线程执行指令。

  2. 实际上,块内的最小线程数是 1。如果每个块只有一个线程,您的代码将正确执行。但是,将块设置为具有 32 个线程的倍数会更有效。这是由于硬件在 32 个线程的“warp”中调度操作的方式。

  3. 您可以交叉编译您的程序。您可以在仿真模式下运行它,即 CPU 正在“仿真”一个 CUDA GPU,但要在硬件上运行,您需要一个 NVIDIA GPU(启用 CUDA,任何最近的东西,2006 年以后左右都可以)。

当前一代高端 GPU 有 240 个内核 (SP),您可以将其视为在任何给定时刻执行 240 个线程,但将 GPU 视为同时执行数千个线程是有用的,因为多个线程的状态(上下文)已加载。

我认为重要的是要认识到 CPU 线程和 GPU 线程之间存在差异。它们确实具有相同的名称,但 GPU 线程是轻量级的,通常在一小部分数据上运行。考虑一个(一组)CPU线程执行非并行工作可能会有所帮助,然后每个CPU线程分叉成数千个GPU线程以进行数据并行工作,然后它们加入回CPU线程。显然,如果你能让 CPU 线程与 GPU 同时工作,那就更好了。

请记住,与 CPU 不同,GPU 是一种吞吐量架构,这意味着程序应该创建许多线程,而不是缓存来隐藏延迟,以便在一些线程等待数据从内存返回时,其他线程可以执行。我建议观看GPU 技术大会上的“Advanced C for CUDA”演讲以获取更多信息。

于 2009-12-30T19:24:51.327 回答
2
  1. 是的。每个 GPU 都是一组矢量处理器SIMD(单指令多数据)处理器。在单个线程向量中(可以是 32、64 或其他数量,具体取决于 GPU),每个线程在锁步中执行内核的相同指令。这个基本单位有时被称为“扭曲”或“波前”,有时也被称为“SIMD”。

    32 似乎是 NVidia 芯片的典型值,64 是 ATI 的典型值。IIRC,Itel 的 Larrabee 芯片的数量应该会更高,如果该芯片曾经制造过的话。

  2. 在硬件级别,线程在这些单元中执行,但编程模型允许您拥有任意数量的线程。如果您的硬件实现 32 宽波前并且您的程序只请求 1 个线程,则该硬件单元的 31/32 将处于空闲状态。因此,以 32 的倍数(或其他)创建线程是最有效的做事方式(假设您可以对其进行编程,以便所有线程都进行有用的工作)。

    硬件中实际发生的情况是每个线程至少有一个位。指示线程是否“活动”。波前 32 中多余的未使用线程实际上会进行计算,但无法将任何结果写入任何内存位置,因此就好像它们从未执行过一样。

    当 GPU 为某些游戏渲染图形时,每个线程都在计算单个像素(如果打开了抗锯齿,则为子像素),并且每个被渲染的三角形都可以有任意数量的像素,对吗?如果 GPU 只能渲染包含 32 像素的精确倍数的三角形,它就不能很好地工作。

  3. goger 的回答说明了一切。

  4. 尽管您没有特别询问,但对于您的 GPU 内核来说,避免分支也非常重要。由于波前中的所有 32 个线程都必须同时执行相同的指令,那么当if .. then .. else代码中有 和 时会发生什么?如果warp中的一些线程想要执行“then”部分,而一些线程想要执行“else”部分?答案是所有 32 个线程都执行这两个部分!这显然需要两倍的时间,因此您的内核将以一半的速度运行。

于 2009-12-30T20:20:48.230 回答