参考:
CUDA C++ Programming Guide
1.1 使用 GPU 的好处
The Graphics Processing Unit 图形处理单元(GPU)在价格和功耗相似的情况下提供比 CPU 高得多的指令吞吐量和内存带宽。许多应用程序利用这些更高的功能在 GPU 上运行速度比在 CPU 上运行得更快(请参阅 GPU 应用程序)。其他计算设备(如 FPGA)也非常节能,但提供的编程灵活性远低于 GPU。
GPU 和 CPU 之间存在这种功能差异,因为它们在设计时考虑了不同的目标。虽然 CPU 被设计为擅长以尽可能快的速度执行一系列操作(称为线程),并且可以并行执行几十个这样的线程,但 GPU 被设计为擅长并行执行数千个线程(摊销较慢的单线程性能以实现更大的吞吐量)。
GPU 专用于高度并行计算,因此设计为将更多的晶体管用于数据处理,而不是数据缓存和流量控制。原理图 1 显示了 CPU 与 GPU 的芯片资源分布示例。
图1 GPU 将更多晶体管用于数据处理
将更多的晶体管用于数据处理,例如浮点计算,有利于高度并行的计算; GPU 可以通过计算隐藏内存访问延迟,而不是依赖大型数据缓存和复杂的流量控制来避免长时间的内存访问延迟,这两者在晶体管方面都很昂贵。
通常,应用程序具有并行部分和顺序部分的混合,因此系统设计时混合了 GPU 和 CPU,以最大限度地提高整体性能。具有高度并行性的应用程序可以利用 GPU 的这种大规模并行特性来实现比 CPU 更高的性能。
1.2. CUDA:通用并行计算平台和编程模型
2006 年 11 月,NVIDIA 推出了 CUDA,这是一种通用并行计算平台和编程模型,它利用 NVIDIA GPU 中的并行计算引擎,以比 CPU 更有效的方式解决许多复杂的计算问题。
CUDA 附带一个软件环境,允许开发人员使用 C++ 作为高级编程语言。如 [图 2] 所示,支持其他语言、应用程序编程接口或基于指令的方法,例如 FORTRAN、DirectCompute、OpenACC。
图 2 GPU 计算应用。CUDA 旨在支持各种语言和应用程序编程接口。
1.3. 可扩展的编程模型
多核CPU和众核GPU的出现意味着主流处理器芯片现在是并行系统。挑战在于开发能够透明地扩展其并行性的应用软件,以利用越来越多的处理器内核,就像 3D 图形应用程序透明地将其并行性扩展到具有大量不同内核的众核 GPU 一样。
CUDA 并行编程模型旨在克服这一挑战,同时为熟悉 C 等标准编程语言的程序员保持较低的学习曲线。 它的核心是三个关键的抽象——线程组的层次结构、共享内存和屏障同步——它们只是作为一组最小的语言扩展暴露给程序员。
它的核心是三个关键的抽象——线程组的层次结构、共享内存和屏障同步——它们只是作为一组最小的语言扩展暴露给程序员。
这些抽象提供细粒度数据并行性和线程并行性,嵌套在粗粒度数据并行性和任务并行性中。它们指导程序员将问题划分为可以通过线程块独立并行解决的粗略子问题,并将每个子问题划分为更精细的部分,这些子问题可以由块内的所有线程并行协作解决。
这种分解通过允许线程在解决每个子问题时进行合作来保留语言的表达能力, 同时实现自动可扩展性。事实上,每个线程块可以以任何顺序、并发或顺序在 GPU 内任何可用的多处理器上进行调度,因此编译的 CUDA 程序可以在任意数量的多处理器上执行,如图 3 所示,只有运行时系统需要知道物理多处理器计数。
这种可扩展的编程模型允许 GPU 架构通过简单地扩展多处理器和内存分区的数量来跨越广泛的市场范围:从高性能发烧友 GeForce GPU 和专业的 Quadro 和 Tesla 计算产品到各种廉价的主流 GeForce GPU(有关所有支持 CUDA 的 GPU 的列表,请参阅支持 CUDA 的 GPU)。
图 3 自动扩展性
Note
GPU 是围绕流式多处理器 (SM) 阵列构建的(有关详细信息,请参阅硬件实现)。多线程程序被划分为彼此独立执行的线程块,因此具有更多多处理器的 GPU 将比具有较少多处理器的 GPU 在更短的时间内自动执行程序。