1. GPU 并行计算
1.1. 概述
GPU(Graphics Processing Unit)图形处理器在同等价格和功耗的范围内,可以提供比 CPU 更高的指令吞吐量和内存带宽。基于这些优势,很多并行化的应用程序在 GPU 上比在 CPU 上运行得更快。其他计算设备,如 FPGA,也非常节能,但其编程灵活性远低于 GPU。
GPU 和 CPU 之间存在功能差异,是因为它们在设计时就考虑了不同的目标。CPU 旨在以最快的速度执行一系列操作(称为线程)并且可以并行执行几十个这样的线程,而 GPU 则擅长并行执行数千个线程(分摊较慢的单线程性能,以实现更大的吞吐量)。
GPU 专门用于高度并行计算,因此在设计上将更多晶体管用于数据处理,而不是数据缓存和流量控制。图 1 显示了 CPU 与 GPU 的芯片资源分布示例。

图1 CPU 和 GPU 硬件逻辑结构对比
将更多的晶体管用于数据处理,有利于高度并行计算; GPU 可以通过计算隐藏内存访问延迟,而不是依赖大型数据缓存和复杂的流量控制来避免长时间的内存访问延迟,而这两者都需要昂贵的晶体管。
通常,应用程序既包含并行部分,又包含顺序部分,因此系统设计时混合使用 GPU 和 CPU 以最大限度地提高整体性能。具有高度并行性的应用程序可以利用 GPU 的这种大规模并行特性,来实现比 CPU 更高的性能。
1.2. 可扩展编程模型
多核 CPU 和众核 GPU 的出现意味着现在主流的处理器芯片是并行系统。我们面临的挑战是如何开发应用软件,能够透明地扩展其并行性,从而充分利用不断增加的处理器内核,就像 3D 图形应用程序以透明的方式将其并行性扩展到具有广泛不同内核数的众核 GPU 一样。
MUSA 并行编程模型旨在克服这一挑战,同时为熟悉标准编程语言(如 C)的程序员保持较低的学习曲线。
其核心是三个关键的抽象:线程组的层次结构、共享内存和屏障同步,这些抽象概念作为最小的语言扩展集简单地暴露给程序员,如图 2 所示。

图2 GPU 编程结构中的 thread、block 和 grid
这些抽象提供细粒度的数据并行性和线程并行性,嵌套在粗粒度的数据并行性和任务并行性中。它们指导程序员将问题划分为可由线程块并行独立解决的粗略子问题,并将每个子问题划分为可由块内所有线程并行协作解决的更细小的部分。
这种分解通过允许线程在解决每个子问题时进行协作来保留语言表达能力,同时还实现了自动可扩展性。事实上,每个线程块都可以在 GPU 中的任意可用多处理器上以任意顺序、并发或顺序进行调度,以便编译后的 MUSA 程序可以在任意数量的多处理器上执行,并 且运行时系统只需要知道物理多处理器数量。
金融建模、自动驾驶、智能机器人、新材料发现、脑神经科学、医学影像分析以及人工智能时代的科学研究极度依赖计算力的支持。GPU 将起到越来越重要的作用。

