CPU和GPU双低效,未来性能提高万倍只看它?
2017-05-30
2008年,《三体2:黑暗森林》里写到:
真的很难,你冬眠后不久,就有六个新一代超级计算机大型研究项目同时开始,其中三个是传统结构的,一个是非冯结构的,另外两个分别是量子和生物分子计算机研究项目。但两年后,这六个项目的首席科学家都对我说,我们要的计算能力根本不可能实现。量子计算机项目是最先中断的,现有的物理理论无法提供足够的支持,研究撞到了智子的墙壁上。紧接着生物分子计算机项目也下马了,他们说这只是一个幻想。最后停止的是非冯结构计算机,这种结构其实是对人类大脑的模拟,他们说我们这只蛋还没有形成,不可能有鸡的。最后只有三个传统结构计算机项目还在运作,但很长时间没有任何进展。
好在我们要的计算机还是出现了,它的性能是你冬眠时最强计算机的一万倍。传统结构?传统结构,能从摩尔定律这个柠檬里又榨出这么多汁来,计算机科学界都很吃惊。但这次,亲爱的,这次真的到头了
那是我读计算机体系结构专业博士的最后一年,当时我对此嗤之以鼻:摩尔定律怎么可能还有那么多油水可以榨。工艺极限近在眼前,不用智子出手,摩尔定律就会死翘翘了;传统结构更是没戏,CPU的架构已经被研究到头了,从2000年后,几乎没有捣鼓出啥新东西。
所以,这个“一万倍”,真的是好科幻好科幻啊。
回顾三体2出版之后的这九年,工艺进展步履维艰,微架构亮点寥寥,CPU的性能每一代都是挤牙膏。一切都好像在印证我悲观的预期——计算机硬件的性能,好像真的提升不上去了。
但是,从去年开始,“科幻”般的事件相继降临:
2016年3月,AlphaGo战胜李世石,它使用了1202个CPU和176个GPU
2016年4月,NVidia发布Pascal架构,峰值性能达到11TFLOPS/s,黄仁勋在接受新智元专访时表示,半导体技术迭代在放缓,但GPU Pascal架构比上一代性能在两年内提升了近十倍,因此可以说我们正处在一个“超级摩尔定律”时代。
今年5月11日,NVidia发布Volta架构,峰值性能达到120TFLOPS/s
今年5月11日,Google公布TPU二代,峰值性能达到180TFLOPS/s,且可以通过Google Cloud访问
今年5月23日AlphaGo重出江湖并且毫无悬念地战胜了柯洁;24日,DeepMind CEO 哈萨比斯和AlphaGo项目总负责人David Silver 在新闻发布会上接受媒体采访时表示,AlphaGo实际上是在谷歌云端的单一一台机器上运行的,此机器建立于二代TPU之上(据说这台机器使用了4块TPU)
在摩尔定律已经严重减速甚至失效的今天,我们实实在在地看到了算力的大幅度提升,而且这场算力的军备竞赛还在继续!
而我,也改变了自己悲观的预期,相信在不远的将来,“摩尔定律结束之后,性能提升一万倍”,将不会是科幻,而是发生在我们眼前的事实。
这是不是太疯狂了?设计计算机硬件的技术宅男们,凭什么做到这一点?凭TPU所代表的技术路线以及新的商业模式。且听我慢慢道来。
为什么CPU是低效的
在解释凭什么能做到“摩尔定律之后一万倍”之前,我们先聊聊为什么CPU和GPU无法担此重任。
如果你问我,CPU最大的特点是什么?我会说:它给程序员一个假象,让你感觉访问大容量的内存任何一个位置的延迟都是相同的,而且和做一次加法的延迟差不多,近乎为0。
制造这个假象非常困难。要知道CPU所采用的Logic生产线,同内存用的Memory生产线,有天壤之别。简单地说,由于某种底层的物理定律,Memory产线无法实现CPU所需要的高速度,Logic产线无法实现内存所需要的大容量。更糟糕的是,Memory制程相对于Logic制程还越来越慢,从1986年到2000年,Logic每年提速55%,而Memory只有10%。
何为“快”“慢”?口语中的“快”,可以指延迟小(从开始到结束间隔的时间短),也可以指带宽大(单位时间内通过的量大),说“高铁快”,指前者,说“网速快”,指后者。内存的带宽其实增长得还凑合,486时代CPU跑100MHz,SDRAM内存带宽为100MT/s;如今CPU达到2GHz~3GHz,DDR4内存带宽3200MT/s。虽然内存带宽有了几十倍的提升,但从发出读请求到内存条返回数据的延迟,这二十年来只减小了两倍多。
且不说外行人,很多初级程序员都不知道内存的延迟如此糟糕,即使是资深程序员,在大多数时候,也可以在编码中忽略它,为什么?这都是CPU的功劳。CPU使用了很多复杂的技术来隐藏内存的延迟,例如:
CPU使用非常大量的片上存储来做cache(缓存),把程序经常访问的数据放在片上,这样就不必访问内存了
CPU用复杂的技术猜测程序即将访问哪些数据,用预取的方式,提前把这些数据从内存中搬运到片上
当某一段程序由于等待内存数据而卡住无法执行时,CPU用乱序的方式,执行接下来的片段
使用超线程技术,当一个程序因为等待内存数据而卡住时,选择另外一个程序来执行
CPU的硅片上,绝大多数面积都是用来制造“内存访问近乎零延迟”这一假象的,真正用来做运算的逻辑,所占面积甚至不到1%——这就是它低效的根源。
CPU诞生于Logic和Memory的速度差不多的年代,那个时候,程序员就已经习惯于假设“内存访问近乎零延迟”,为了保证对软件的兼容,CPU多年来不惜一切代价维持这一假象。积重难返,时至今日,软件已经无法通过CPU来充分利用集成电路制造工艺所提供的澎湃动力。
为什么GPU是低效的
再用一句话来总结GPU最大的特点:它给程序员一个假象,让你感觉GPU上面有数十万个小程序在运行,彼此相安无事。
GPU的架构,简单地说,就是把类似CPU超线程的技术用到极致来隐藏内存访问的超长延迟。GPU里面有数千个小核心,每个都可以看成是个小CPU,与此同时,它同时运行最多数十万个小程序,大多数程序会因为等待访存而卡住,真正在小CPU上执行的程序只有数千个。
因为同时在工作的小核心有数千个,GPU比起CPU,单位时间内完成的运算量大多了。但它也有软肋,那就是:这数十万个小程序,彼此之间根本不可能相安无事,它们会抢存储带宽,抢得很凶。GPU要付出的管理代价相当高:
要做复杂的缓存,以备一块从显存取来的数据被很多小核心使用
访存接口只有8个,能发出访存请求的小核心确有数千个,必须分析它们发出的请求,把访问相邻地址的请求捏在一起作为一个请求送给显存
访存带宽必须做得远高于CPU,才能喂饱数千个小核心
数千个小核心上,每个时钟周期所运行的小程序都可能不一样,每个小程序的上下文都要保留,以备将来唤醒。为了存储上下文所付出的片上Memory的面积,堪比CPU上的庞大缓存
相对于CPU,GPU制造假象的能力稍逊一筹,稍有经验的GPU程序员,都明白要尽可能让GPU上并行跑的数十万小程序在访存时呈现一定的规律,否则GPU的效率会大打折扣。
GPU的定位,不单单是图形加速,而是所有的有海量数据并行运算的应用,因此它必须非常通用,不能对其上运行的数十万个小程序做限制。事实上,这数十万的小程序每个都可以任意访问到显存的所有位置,而且访问的位置各不相同,在这种情况下,GPU也要保证功能的正确性,哪怕跑得慢些。管理和组织这数十万个不受限制的小程序所付出的硅片面积代价和内存带宽的代价,是GPU低效的根源。
为什么FPGA只是过渡方案
CPU和GPU的架构都有非常沉重的历史包袱,体现在:
它们都有很强的通用性,不能仅仅只针对某个领域做优化
它们都有很强的兼容性,过去编写的程序必须能够运行
它们都有稳定而庞大的程序员队伍,这些程序员的思维方式不加改变的话,它们就不能放弃提供那些“假象”
这些也是非常伟大而甜蜜的包袱,正因为背负着它们,CPU和GPU厂商才能在它们既有的市场里呼风唤雨,并且把竞争者挡在门外。
如果扔掉这些包袱,设计全新的架构,就可以做到:
仅仅针对某个领域做优化
不考虑对过去软件的兼容
用全新的方式对其编程,不拘泥于之前的思维定势
这样设计出的架构,对其目标领域,性能指标会大幅度超越CPU和GPU这类通用架构。原因非常浅显易懂,通用性和最优化无法两全。历史上已有先例,当计算化学领域和天体物理领域对计算性能的需求无法被满足时,分别有科学家们为它们开发出了专用的Anton和Grape-DR计算机。只不过它们的专业性太强,不为大众所知。
如今,当CPU和GPU的架构已经无法满足人工智能应用对速度、功耗和成本的需求时,寻找新的架构成为了大家共同的选择。在寻找新架构的过程中,FPGA起到了开路先锋的作用。
FPGA是什么?如果说CPU和GPU是在架构级别做到“通用”的话,FPGA就是在更低一级的电路级做到了“通用”。通过硬件描述语言对FPGA编程后,它可以模拟任何一种芯片的架构,包括CPU和GPU的架构,通俗地说,FPGA是一种可编程的“万能芯片”。它非常适合探索性的、小批量的产品。
我们已经看到了很多的FPGA方案,实现了比GPU更好的速度、功耗或成本的指标。但是,FPGA依然无法摆脱“通用就无法最优”这一规律的制约。它之所以还能体现出相当的优势,是因为在一个软硬件系统中,算法的影响远大于硬件架构,而硬件架构的影响又远大于电路——在电路级别做“通用”付出的代价,比起在架构级别做“通用”的代价,还是小得多了。
一旦FPGA给某个专用架构趟出路来之后,它就会退居幕后,让位给更专用的ASIC。
TPU代表了未来的方向
这次同柯洁对阵的AlphaGo,采用了Google自研的第二代TPU。TPU的特点是:
仅仅针对线性代数做优化
不兼容CPU或GPU的程序
用全新的方式对其编程
用ASIC而非FPGA的方式来实现
深度学习所使用算法,绝大多数可以被映射为底层的线性代数运算。TPU(Tensor Processing Unit)中的Tensor,就是线性代数中的基本数据类型。线性代数运算有两大特点:Tensor的流动非常规整且可预期;计算密度很高,即每个数据都会历经非常多次的计算。这两大特点使得线性代数运算特别适合做硬件加速——所有用来制造“假象”的逻辑都不再必要,每个晶体管都可以用做有意义的运算或存储。
TPU上无法运行CPU上跑的Java或C++程序,也无法运行GPU上的CUDA程序。虽然尚未有公开信息,但它的编程方式非常可能是这样:TensorFlow把神经网络用一种中间格式表示出来,然后这种中间格式被编译器转换为TPU上独特的程序。这种中间格式被称为TensorFlow XLA,它也将是TensorFlow支持其它线性代数加速器的工具。
Google之所以选择ASIC而非FPGA,与其说是它的眼光好,不如说是它的魄力强。内行人都知道ASIC效能远超FPGA,但仍然有很多人不敢选择ASIC,为什么?自己做ASIC的风险太大:周期长,投入多,门槛高。一旦芯片做错,就和石头无异,落个血本无归。当年Apple决定自己做芯片时,并没有直接组建队伍,而是收购了P.A. Semi;这么多年后,成果赫赫,但依然不敢在Mac电脑中使用自研的CPU来淘汰Intel的芯片。而Google在短短几年内,组建了队伍,设计了合理的架构,做出了能work的芯片,并且敢于在自己的云上部署自己的产品,只能说一声“服!”
Google是一家伟大的公司,在它发布MapReduce、GFS和BigTable的论文之前,这些东西被普遍认为是不可能完成的。相信很多人在看到装备TPU的AlphaGo战胜柯洁之前,也会认为TPU是不可能完成的。历史证明,Google能做的事情,别人起码可以模仿个七八分。现在大家应该相信,在一个足够重要应用领域中,完全可以把优化和定制做到晶体管级别,而不是只做到某种现成的芯片架构的级别。这不但可行,而且必要,因为你不这么做,竞争对手也会这么做。
硬件的开源时代
摩尔定律的通俗表示是:每一美元所能买到的电脑性能,将每隔18-24个月翻一倍以上。过去三十年,拜摩尔定律所赐,我们见证了超过百万倍的性价比提升。未来我们所能看到的这一万倍,也应该按照“单位成本所能买到的电脑性能”来计算。
CPU和GPU这种通用架构,它们的历史包袱不仅仅导致了优化难以开展,还导致了:一、垄断导致的超额利润;二、过度复杂所带来的研发成本上升。于是,芯片的价格居高不下。
未来,当特定领域的定制芯片大行其道时,这些芯片的价格也将显著降低。原因在于:一、不再有垄断;二、没有历史包袱所带来的研发成本;三、开源所带来的研发成本降低。
硬件开源过去有过尝试,但无大成,原因是多种多样的。但从长远角度看,所有的基础设施,被广大厂商共享的,最终都会走向开源的路子。如果说Intel的CPU是大地(所有的优化不能做到比它更加底层),那么Linux、Python和PHP就是大地之上最底层的基础设施,它们是开源的;如果说GPU+CUDA是大地,那么各种深度学习的框架就是最底层的基础设施,它们也都是开源的。如果未来晶体管是大地,那么毫无疑问芯片的架构也会出现各种开源方案。
这一切才刚刚开始。这个月NVidia做了两件有趣的事:赞助了开源CPU架构RISCV在上海举办的workshop;宣布Xavier自动驾驶芯片中的针对线性代数的硬件加速模块DLA将开源。大厂支持开源,绝不是搞慈善,而是为了扼杀竞争对手,赢得业界事实标准的控制权。但开源的后果,必然是降低设计门槛,降低整个行业的研发成本。
我们的星辰大海:从应用到晶体管的全栈优化
对于从事计算机体系结构专业的同仁而言,这是最好的时代,半导体制造的先进工艺进展缓慢,但软件的各种应用需求还在不断涌现,软硬件接口逐渐模糊,成熟工艺的成本不断下降。为了优化特定应用,做深入到晶体管级的全栈优化成为一个现实的选项。只要正确地设计专用架构,使用成熟工艺也可以轻松超越GPU和CPU这种通用架构,哪怕它们采用最先进的制造工艺。
这是一个全新的世界,以往的利益格局和设计思想都将被打破,谁也无法预知将会发生怎样的兴衰变迁。但这就是我们的星辰大海,一起来探索和历险吧!