为什么我可以在 GeForce GTX 480 GPU 上运行 23,000 个 CUDA 线程?

Dav*_*aux 5 gpu

有人告诉我,GeForce GTX 480 GPU 可以同时运行 23,000 个 CUDA 线程。但是,我很困惑为什么。

该 GPU 的每个核心包含 2 组 16 个 SIMD 单元。每个 SIMD 单元有 8 个 ALU 和指令上下文。GPU 上有 15 个内核。

因此,这个 GPU 不应该一次只能运行 2 * 16 * 8 * 15 = 3840 个 CUDA 线程吗?

Wyz*_*ard 6

GPU 内核可以有效地同时运行多个线程,这是因为它们在线程之间切换以隐藏延迟。事实上,您需要在每个内核上运行多个线程才能充分利用您的 GPU。

GPU 是深度流水线的,这意味着即使每个周期都开始新指令,每个单独的指令也可能需要多个周期才能运行。有时,一条指令取决于前一条指令的结果,因此在前一条指令完成(退出流水线)之前,它无法启动(进入流水线)。或者它可能依赖于需要几个周期才能访问的 RAM 中的数据。在 CPU 上,这将导致“流水线停顿”(或“气泡”),这会使一部分流水线闲置多个周期,只等待新指令开始。这是对计算资源的浪费,但这是不可避免的。

与 CPU 不同,GPU 内核能够非常快速地在线程之间切换——大约为一两个周期。因此,当一个线程由于下一条指令无法启动而停滞几个周期时,GPU 可以切换到其他线程并启动其下一条指令。如果该线程停止,GPU 会再次切换线程,依此类推。这些额外的线程在流水线阶段做有用的工作,否则在这些周期中会空闲,所以如果有足够的线程来填补彼此的间隙,GPU 就可以在每个周期的每个流水线阶段工作。任何一个线程中的延迟都被其他线程隐藏。

这与英特尔超线程特性的原理相同,它使单个内核显示为两个逻辑内核。在最坏的情况下,运行在这两个内核上的线程会相互竞争硬件资源,并且每个都以半速运行。但在许多情况下,一个线程可以利用另一个线程不能使用的资源——目前不需要的 ALU,由于停顿而空闲的流水线阶段——因此两个线程都以超过 50% 的速度运行如果单独运行,他们会实现。GPU 的设计基本上将这种优势扩展到两个以上的线程。

您可能会发现阅读 NVIDIA 的CUDA 最佳实践指南很有帮助,特别是第 10 章(“执行配置优化”),其中提供了有关如何安排线程以保持 GPU 忙碌的更多详细信息。