编者按
在过去的一年(2022年),软硬件融合公众号的很多文章,都围绕着“超异构计算”这个重要的主题展开。也和很多朋友交流超异构计算相关的话题,大家提到的最主要的一个问题是:超异构和异构的本质区别在哪里?
因此,我整理了今天的这篇文章,通过异构计算的历史、发展、挑战、以及优化和演进等方面的分析,来进一步阐述从异构走向异构融合(即超异构)的必然发展趋势。
1971年Intel发明全球第一款商用的CPU处理器,在之后的上世纪70-90年代,CPU(核)经历了翻天覆地的变化:
经过这些创新之后,逐步的触达了(架构/微架构层次的)CPU(核)性能的上限。不考虑工艺升级的影响,单个处理器核的性能几乎挖掘到极致,持续增加性能的希望,不得不落在多个处理器核并行的路径上来。
IBM公司于2001年推出IBM Power4双核处理器,是世界上第一款多核处理器。随后,AMD和Intel分别推出了各自的双核处理器。随着时间推移,更多的CPU核心被集成进了CPU芯片。目前,最新的AMD EPYC™ 9654 CPU具有96个核心192个硬件线程的超高并行能力。
GPGPU本质上是数以百/千计的高效能的小CPU组成的众核并行计算处理器。如NVIDIA的图灵架构GPGPU,总共72个SM,每个SM由64个CUDA核、8个Tensor核、1个RT核、4个纹理单元,总计有4608个CUDA核、576个Tensor核、72个RT核、288个纹理单元。
GPU众核(数千个)和CPU多核(数十个)的区别在于:CPU核是高性能的大核,足够高性能的同时也足够复杂,面积功耗成本等方面的代价也高,单位计算的成本较高;而GPU核是高效能的小核,每个核的性能较低,但数以千计的小核并行起来的性能足够高,单位计算的功耗面积等成本较低,但单核的性能不足以满足通用计算单个线程性能的要求。
CPU是图灵完备的(在这里,图灵完备可以通俗的理解成可以独立运行的处理器平台),因此CPU可以单独的作为软件系统的运行平台。而GPU等其他加速处理器则不同,这些平台是非图灵完备的,或者说无法独立运行,只能在CPU的协助下才可以运行。也因此,我们通常见到的异构计算系统都是“CPU+xPU加速处理器”的架构(xPU特指其他各类非CPU处理器)。
上世纪80-90年代,每18个月,CPU性能提升一倍,这就是著名的摩尔定律。如今,CPU性能提升每年只有3%,要想性能翻倍,需要20年。CPU的性能提升已经达到瓶颈,难堪大任。
虽然CPU的性能提升几乎停滞,但对算力(性能是微观,算力是宏观)的需求,是永无止境的:
算力需求越来越大,异构成为了(架构层次)性能提升的主要手段。
实际上,硬件实现同构或异构并行的门槛相对不高。但受限于人类的思维习惯,驾驭并行硬件平台,也即并行编程,的难度较大;特别是异构并行,编程难度更大。异构并行编程不仅仅涉及众多并行线程的编程,还涉及到加速处理器和Host CPU的交互编程,还包括这两者的交叉同步。
在并行系统里,通过(手动)编程实现单个软件内部多个不同线程的并行,这种方式编程难度大,系统复杂,而且对并行资源的利用效率不高,这不是主流的方式。
在CPU同构并行的硬件平台上,更多的是通过操作系统的多线程调度能力以及虚拟化的多系统隔离的方式,实现宏观意义上的多个系统或多个软件的并行,而不是通过(手动)编程实现单个软件内部的线程级并行。
GPU众核编程则要更加复杂。为了降低编程门槛,GPU上运行的程序并不是完全“自由”的,而且强加了一些约束或底层细节屏蔽,以此来降低编程难度。比如SIMD方式的单线程多处理器并行执行(多个处理器执行的是相同的程序),再比如通过底层的软件或硬件机制实现统一内存,还比如通过框架和开发库等方式进一步降低开发难度,等等。通过这些方式,可以显著的提高异构并行的性能利用效率、提高编程效率、降低编程难度等。
2006 年 11 月,NVIDIA推出了CUDA框架,这是一种通用并行计算平台和编程模型,它利用NVIDIA GPU中的并行计算引擎以比CPU更有效的方式解决许多复杂的计算问题。经过十多年的发展,NVIDIA建立了基于其GPGPU的非常强大的CUDA异构编程框架和生态。
随着AI大潮的到来,对算力的需求不断快速增长,传统CPU的算力平台越来越难以满足业务算力的需要。这进一步推动NVIDIA GPGPU和CUDA成为了炙手可热的行业“明星”,使得NVIDIA成为全球市值最高的芯片公司。
对大算力芯片来说,生态是成功的第一关键。
DSA是在定制ASIC的基础上回调,使其具有一定的软件可编程灵活性。DSA出现的原因主要有:
图灵奖获得者John Hennessy和David Patterson在其2017年说,未来十年是体系机构的黄金年代,在CPU性能达到瓶颈的情况下,要大幅提高性能并且优化成本和能耗的唯一途径是DSA,即针对特定领域的特殊需求定制处理器。
2016年发布的谷歌TPU是第一款DSA架构的处理器,从此之后,各种类型的符合DSA概念的加速处理器如雨后春笋般涌现。
DSA无法包治百病。
所谓“成也萧何败也萧何”,DSA的优势是领域定制,劣势也是领域定制:
我们依据指令复杂度从简单到复杂,可以把典型的处理器引擎划分为CPU、协处理器、GPU、FPGA、DSA和ASIC。CPU可以理解成纯软件,协处理器是附属于CPU,在硬件上跟CPU是一体的。因此,可以作为加速处理器xPU的处理器引擎类型只有后面四个。
异构计算的核心矛盾在于:系统越复杂,越需要选择灵活的处理器;性能挑战越大,越需要选择定制的处理器。本质原因在于,单一处理器无法兼顾性能和灵活性:
随着异构计算成为计算的主流架构,也随着异构的处理器越来越多,最终的系统一定不是Host+某个唯一的xPU加速处理器,而是Host+很多个xPU加速处理器的模式。这样,多个异构协同计算的问题就出现了:
维度一:处理器引擎的类型。灵活性和性能是系统架构的核心矛盾,更多的灵活性,也意味着更加易于编程,系统更好驾驭,与此同时却意味着更低的性能。许多设计权衡其实都在根据业务场景的特点,在灵活性和性能的天平上左右摇摆:到底是应该偏向灵活性的CPU多一些,还是偏向极致性能的ASIC多一些。
维度二,处理器引擎类型的数量。系统的驾驭难度,也跟处理器类型的数量有关:
更多类型的处理器引擎,又是一个艰难的抉择:一方面意味着性能的进一步提升,另一方面意味着更高的编程难度。
越来越“卷”,随着处理器引擎越来越多,每个处理器引擎其实都突破了我们通常意义上的各自边界,侵入到其他处理器引擎的领地。例如:
处理器引擎不断扩展,在引擎内部形成了某种程度上的“异构”能力,这可以看做是异构计算优化权衡的第三个维度。
前面我们从三个维度介绍了异构计算的优(左)化(右)权(摇)衡(摆):要想获得灵活性,势必会降低性能(效率);而要想获得性能,势必会降低系统的灵活性,增加系统的复杂度,使得系统难以驾驭。
但考虑到业务应用对算力的渴求,我们不得不“迎难而上”,不断的提升硬件平台的性能。这样势必会增加整个系统的复杂度,也进一步提高了编程的难度。
受限于前面提到的异构计算孤岛问题,把多个异构计算系统合并到一起的时候,不能简单的拼凑,而是要重新构建一个新的超异构计算系统。
接下来,更重要的问题来了:如何驾驭比异构并行更复杂的超异构融合计算?
串行计算符合人类思维,编程相对最简单;同构并行的编程,就要复杂很多;异构并行,则更是难上加难;那么超异构并行呢?那就是难上加难再加难。
要想驾驭超异构,核心的思路跟驾驭异构计算的思路一致,就是要降低软硬件系统的复杂度。
接下来,我们详细介绍一些主要的降低复杂度的方法。
从系统的角度,多个小系统组成一个大系统,多个大系统组成一个宏系统。反过来,复杂大系统可以分解成若干个简单的小的系统,大系统由多个小系统和小系统间的交互组成。
相比大系统,小系统必然更加简单;针对分解后的小系统,则可以更加容易的驾驭。
应用,是完全不可确定的,针对应用,只能采用CPU处理器。如果完全“躺平”(不加约束),并不考虑平台上面运行什么软件任务,那么极端保守的做法就是选用CPU平台。CPU平台什么任务都能支持,但劣势是性能是最差的,成本代价是最高的。
一个系统并不都是应用类型的任务。系统可以看作是很多工作任务的组合,这些工作任务都各有特点,我们可以针对任务的特点,把任务进行分类:
针对不同任务的灵活性/性能特征,把任务划分到这三个层次,然后采取各自特征能力相符的处理器平台,可以做到满足整个系统最极致灵活性的同时,实现整个系统最极致的性能。
架构(硬件的具体实现是微架构,而架构指的是软件看到的硬件架构),也可以称为软硬件接口,是系统架构中最核心的概念。
CPU目前有非常流行的RISC-v架构,RISC-v开放架构的价值大家都能够理解。从CPU到ASIC,越往右,处理器的子类型越多,架构的数量也越多。不同类型、不同领域、不同场景、不同厂家、不同架构的处理器,如果不加以约束的话,会导致处理器架构的完全碎片化。越是处理器类型众多,越需要全行业形成共识的开放架构。
软件越来越复杂,业务逻辑变化越来越快,具体的表现就是软件开发者越来越崇尚敏捷开发,两个月一个小迭代,半年一个大迭代。同样由于系统的复杂度提升,硬件却与软件相反,其开发难度越来越大,开发周期1-3年,生命周期5-8年。硬件的迭代周期完全跟不上软件的更新节奏。
因此,需要更进一步的系统架构创新,把传统的软件层次的能力融入到硬件中去。这些能力包括功能的扩展性、资源的弹性和近乎无限的资源扩展、完全的硬件虚拟化、硬件高可用等等,通过这些能力来整体的提升硬件的灵活性。
超异构计算,需要“软硬件融合”来驾驭。
上述这些,仅仅只是开始……
(全文完)