如果结合上面探讨的两种类型的多核处理器设计,有一个很明显的问题是,到底用少数几个强大的单核,还是很多简单的单核最能优化处理器设计呢?问题的困境是:如果每个核很强大,其能提供的总指令吞吐率与其功耗或面积成本呈亚线性关系,投入产出效率较低,但是如果每个核很简单,那么单线程的性能很低,而不幸的是每个应用程序总是有一部分没法并行化,这部分将最终决定整个程序的性能。这篇
文章给了一个很有意思的讨论。问题的一个直白答案是取决于程序的并行性:一个程序到底有多大部分是必需串行执行的?如果这个部分很大,那么少数几个强大的单核是比较理想的方案,而如果这个部分很小,那么倾向于使用更多的较简单的核。最为理想的方案是一个异构多核的设计,这样串行的部分能在一个强大的单核上加速,而可以并行的部分则通过很多很小的核来提速。这个思想的一个很明显体现就是Intel的Sandy Bridge处理器,这个处理器没有遵循以往不断增加核数量的规律,其设计中里既有强大的传统处理器核又有类似GPU的处理器,期望做到异构多核来实现性能的提升,下图就是Sandy Bridge的系统结构:
网络互连为主的处理器无论是总线和交换开关的设计,还是流处理器,就没法从本质上改变多核乃至众核处理器设计上的不可扩展性。改变这种传统的互连,人们提出了使用片上网络的办法,使得未来众多的处理器核通过分布式的通讯方式相互沟通,从而避免了集中的互连设计带来的系统性能瓶颈以及较大的功耗开销。不过当片上集成核的数量不断增加时,如何把这个功能组织起来,并不是一个简单的事情,无论是学术界还是工业界都做了许多的尝试,从目前开来实际结果都不太理想。
第一个真正采用网络来连接片上很多核的是2002年MIT一组研究人员提出来的RAW众核处理器。MIT的RAW处理器第一次应用了片上网络的概念。这个设计后来成立了一家公司叫Tilera。RAW的出发点在于看到传统单核处理器中的瓶颈在于操作数网络(scalar operand network)。这个网络把各个ALU中计算出来的数值中间结果存储到寄存器堆,又把寄存器堆里的数给ALU就行操作。随着金属互联线延迟的增加,这个移动操作数回路成为系统瓶颈,成为了导致ALU中晶体管性能提高并不能外化为处理器性能的绊脚石。
解决这个问题的办法是用操作数网络把计算单元(ALU)组织起来,而不是传统意义上的操作数网络为ALU服务。每个操作数通过网络进入到一组ALU里,经过漫长流水线的处理和计算输出出来到网络中,然后送到临近的另一组ALU里,而不必绕回去。这样把每组ALU看成一个“核”,这样就构成了片上网络。下图就是RAW中每个处理器核的结构:
图中可以看到,与其他商业多核处理器不同的是,RAW的片上网络深入到了处理器流水线的内部。接着,既然ALU可以编程,那么操作数网络也可以编程,这样就达成了一个软件可以控制的计算、通信众核系统。当然其网络设计就是一个普通的Mesh网格网络,如下图所示,没啥特殊的。不过这个Mesh其实是由若干个不同功能的网络联合而成,各自负责操作数、片上存储以及I/O等片上通讯的需求。
RAW的难点在于对于应用程序需要就行网络和计算的双重优化,否则程序运行的效率较低。这使得编译器中指令调度不光考虑运算单元的成本,还有通讯的成本,搜索空间和复杂度大大提高。
接下来介绍IBM的Cell处理器,算是工业界探索异构多核设计的先河吧。 Cell的来头还是蛮大的,是IBM,SONY和Toshiba三家大公司为未来的消费电子设计的核心计算引擎。其最典型的应用就是索尼的PS3。Cell的设计采用了环形的片上互连、异构的片上多核、以及片上系统的集成,然后在IBM的90纳米、65纳米和45纳米工艺条件下做了实现,应该说是代表了当时业界的最先进水平。不过不幸的是IBM在2009年年底的时候停止了对Cell的进一步研发,而基于Cell的索尼PS3销售上没有敌过任天堂的Wii(截止2010年9月低,Wii在全世界销售了七千六百万台,而PS3仅有四千两百万台)。这背后的原因在于什么呢?
首先我们来看IBM Cell处理器的设计,其中包含了一个Power processing element(PPE)作为主处理器(其性能相当于64位的Power PC),加上八个Synergistic Processing Elements (SPE)作为协处理器(其性能相当于普通的RISC处理器和一个128位的SIMD),这些处理单元通过一个环形网络就行互连,达到超过200GB每秒的带宽。光从这些数据上来讲,这个多核处理器符合前面讲述的异构并行原理,并且技术也不差。最为不幸的是这个处理器太难编程了。每个协处理器有一个私有的局部存储器(256KB)大小,这个存储器几乎需要程序员来手动调度,它既没有类似于缓存的自动预取,又不与PPE的存储单元共享地址空间。如果要协调好PPE与SPE的工作,除非程序的工作模式是固定的。这样的结果就是处理器理论性能很高,但是实际程序优化起来并不容易,很多程序仅仅能够使用一个类似于PowerPC的PPE。没有多少廉价程序员能够理解如此繁杂的体系结构,愿意在上面做开发。这可能就是Cell最终被IBM停止开发的原因吧。
Intel是最能理解编程的简易性对于一个处理器生命的至关重要性,在当年以x86为代表的CISC和以MIPS、SPARC为代表RISC结构出现争端的时候,Intel为了保证程序的兼容性,保持了x86指令向下兼容。尽管牺牲了一定性能却赢得了软件开发者和客户的认可,而随着半导体技术的推进这些性能牺牲被历史所抹平。针对RAW和Cell都面临的问题,Intel推出了一个保持存储一致性和x86指令集的多核设计:Larabee,作为未来GPGPU时代众核编程的抬头兵。不过这个设计从2008年透出风声到2009年底就被宣布第一代产品难产了。
Larabee的设计野心就是编程的容易性,16(甚至32)个x86的处理器核通过一个环形的片上网络连接在一起,分布式的的片上缓存保持完全的一致性,没有任何特殊的专用硬件单元来增加编程的难度。大部分的优化可以通过软件来完成。完成这样一个设计难度在于两个方面:
- 众核的片上缓存一致性是个难题,现在片上缓存一致性的核的数量支持到8已经很不容易。如果要拓展到16或者32的话,要不性能很低,要不就是得放弃部分一致性的特点,从而使得编程的难度增加。
- Larabee如果想要达到超过Nvidia或者AMD同类GPU产品的性能,必需有一套支持图形图像常见应用的开发工具链,而这个的开发不是一朝一夕之功。
在摩尔定律的作用下,任何的耽搁都会导致产品的流产,Larabee开发的艰巨性决定了其性能跟不上摩尔定律,从而其第一代产品被迫下线。
小结在本文的结尾总结一下所探讨的这些多核乃至众核处理器,可以看到其中的挑战其实并不是在处理器设计本身,而在互连与编程这个两个方面。一个未来会成功的众核处理器提供给开发者一个向下兼容的简单编程模型,并且尽量将互连的影响尽可能的化解。这个目标并不容易实现,很有可能人们不得不最终放弃传统的编程模型,而直接面对众核处理器的互连和编程挑战。本文的续篇中,我们试图分别探讨一下,在互连和编程上研究者们做出的努力。