溯源Tegra K1的变革 从全美达到安腾再到丹佛

  • 来源:微型计算机
  • 关键字:变革,丹佛,安腾
  • 发布时间:2014-10-11 10:12

  在近日召开的半导体工业界盛会Hotchips上,备受关注的NVIDIA丹佛计划拳头产品Tegra K164位版本首次披露其微结构设计:相当激进的七路超标量设计,以往的主流处理器上从未出现过的动态二进制翻译+动态剖析器,不同寻常的指令缓存结构。它的变革跨越之大,几乎完全抛弃了在微处理器市场上早已占据统治地位的硬件主导乱序执行机制。如此锐意进取的新结构到底从何而来,我们又该如何期待它的表现?

  二进制翻译:打破指令集兼容屏障

  2006年,NVIDIA低调收购了一家名为Stexar的创业公司,这家公司截止被收购时创立仅一年,可以说是立足未稳,但是NVIDIA看中的并非Stexar的经营业绩,而是这家公司的核心团队:Stexar的CEO是曾为Intel工作22年之久,从Pentium Pro直至Pentium 4时期长期管理开发工作的Randy Steck,工程团队中据传还有一批来自Intel的好手,其中包括Pentium 4的主要设计者之一Darrell Boggs。

  这一批有生力量加盟NVIDIA不免让人浮想联翩,尽管NVIDIA在这次收购上保持了低调,但是被激起好奇心的国内外媒体都对这次收购给予了许多关注。很多人推测,长期以来倚重图形处理业务的NVIDIA这次将一众处理器设计人才收入麾下,是发出了准备自行开发处理器的信号。加之NVIDIA挑中的这批人身上有难以磨灭的Intel烙印,因此坊间关于NVIDIA打算切入x86领域的消息不胫而走。

  新处理器的开发,必将面临指令集的选择问题。2006年的移动手持设备还没有达到今天这般的全民狂热,当时的处理器市场上ARM与x86划江而治的格局也没有今天这么明晰,从高性能计算到个人电脑,x86都是铁一般的事实标准,如果采用x86之外的其他指令集或者基于自己定义的指令集设计全新处理器,就意味着从操作系统到编译器以及开发工具链,都需要重新构建,更麻烦的是还得说服公司外的广大软件开发者跟进,这几乎是一项不可能完成的任务。当年Intel和HP两大巨头联手推动基于新指令集的安腾遭遇惨败,其中一部分原因就在于此。设计新的处理器难,在新的处理器上培养一套生态系统更是难上加难。因此,摆在NVIDIA面前可供选择的指令集确实不多,从这点上来说,当NVIDIA收购Stexar时爆出的种种切入x86的传闻也不算NVIDIACEO黄仁勋与招入麾下的两位前Intel工程师Gary Brown(左)和Darrell Boggs(右),这两位工程师是Tegra K1芯片的两位主要贡献人。是完全无根无据。

  尝试进入x86阵营必然遭遇Intel和AMD联手经营多年的专利壁垒,如果没有x86指令集授权又硬要兼容x86,摆在NVIDIA面前的最可行选项,就是二进制翻译。所谓二进制翻译,就是将一种指令集下的代码用另外一种指令集表示出来,例如x86指令集中的MOV指令允许访问内存,在ARM指令集上就要翻译成对应的LDR类指令。二进制翻译技术的存在使得指令集之间的天堑被打破,用MIPS这种较为开放的指令集来翻译执行x86也成为可能,这意味着NVIDIA这样位于x86壁垒之外的公司理论上也可以设计自己的处理器进入覆盖面广阔的x86市场。如果二进制翻译的封装足够好,还可以做到对上层软件开发者透明,只需要极小的改动或者完全不需要改动就能把应用程序迁移到新的生态系统中。

  逝去的先驱:全美达“漂流者”

  使用二进制翻译兼容其他指令集这一做法,早在NVIDIA收购Stexar之前,就有一些企业和学术研究机构做出过尝试。其中有多少人曾经尝试过针对x86的二进制翻译已不可考,但幸运的是直到今天,这些试图中仍有一个被反复提及:一家创业公司曾将x86的全系统级二进制翻译付诸现实,在缺乏资金支持又受到Intel持续诉讼重压的情况下推出了一支截然不同的VLIW微结构派系。这家公司的名字叫做全美达(Transmeta),第一代芯片产品被命名为“漂流者”(Crusoe),也就是英国著名作家丹尼尔·笛福的不朽名著《鲁滨逊漂流记》英文原名“Robinson Crusoe”的第二个单词。为x86这样一个定义混乱满是补丁的指令集做一个维持精确异常的全系统级二进制翻译,光是保证功能正确性就已经殊为不易,而全美达还要回应一些针对二进制翻译天生性能劣势的质疑,处境之艰险与荒岛求生的鲁滨逊确实有几分相似。

  二进制翻译从实现方式上来说主要分为两大派系,一派是静态二进制翻译,也就是在程序执行前一次性将所有指令全部翻译好,再开始执行,另一派是动态二进制翻译,主张执行一条翻译一条,翻译过程与执行过程穿插进行。显然,翻译指令的过程是永远无法完全避免的一层性能开销,是永远烙在二进制翻译技术身上的原罪。两害相权取其轻,乍看之下似乎是静态二进制翻译性能更好,一次翻译便可终生无忧,处理器不必在代码执行过程中反复唤起翻译器来解释自己看不懂的指令。而动态二进制翻译则不然,反复唤起翻译器引入的切换开销暂且不提,每一次碰到重复指令都得重复翻译,这是动态二进制翻译的一大硬伤,为了让动态二进制翻译的性能逼近静态二进制翻译,一种通行的做法是引入代码缓存(codecache),将经常使用到的翻译后指令保存在缓存当中,以后再碰到的时候就不用唤起翻译器来重新进行翻译了。代码缓存的加入与其他优化一起,令动态二进制翻译的翻译性能可以与静态二进制翻译有一拼之力。到1995年前后,动态二进制翻译执行的速度已经可以达到原生代码执行速度的三分之一,静态二进制翻译则可以达到原生代码执行速度的二分之一,而全美达“漂流者”以及后继产品的出现,让二进制翻译两大派系的传统站位彻底对调,动态二进制翻译的性能开始反超传统上被认为性能更优的静态二进制翻译,这其中的两大关键技术,就是动态剖析(Profiling)与多层次优化。

  反超筹码:动态剖析+多层次优化

  动态二进制翻译器扮演的角色本质上是一个编译器,不仅要把指令翻译成底层机器能识别的形式,还得做传统的编译器必做的一些编译优化。有的编译优化流程相当复杂,导致翻译器跑了几千条指令才能向后输出一条翻译指令,这个开销大得完全无法接受。因此全美达“漂流者”的二进制翻译器引入了多层次优化,根据代码运行频度的高低,可以选择优化较浅但是翻译速度较快的流程,亦或者选择优化较深但是翻译速度较慢的流程,这是在代码缓存以外的另一项帮助大幅降低翻译开销的技术。但是无论翻译优化如何分层,都只是相当于节流而非开源,分层再细致也只是能够逐渐逼近静态翻译的性能。真正助力动态二进制翻译彻底完成反超的,应该归功于动态剖析。

  传统的编译器优化,需要编译器在代码运行前就提前猜测一些代码中可能出现的特征信息,例如分支的走向,代码块会不会触发异常等。但是巧妇难为无米之炊,这些特征信息往往需要把代码实地跑过一遍才能知道,提前猜测在很多时候只能是盲人摸象。在90年代中期,编译器在SPECint测试集上提前猜测分支走向的准确率仅有75%左右,落后同期的硬件运行时预测器大约20%。为了让编译器获取到这些信息,一个直观的做法是,让程序实地试跑,编译器在一旁观察它的行为特征,等到试跑结束,编译器已然胸有成竹。最激进的一些编译器优化往往需要试跑的介入才能有效完成,这个过程被通称为剖析。尽管剖析具备更好的性能优化潜力,但是这项技术长期被束之高阁,因为程序的运行也需要人来给定运行所需的输入数据,而大部分开发者并不愿意接受这么麻烦的编译流程,大家想要的只是一次无需干涉的自动化编译,然后上线部署。退一步来说,就算程序员们愿意给一次输入,编译器也不会满足,因为代码的运行时特征与输入数据相关,不同的输入数据可以导致代码表露出不同特征,为了实现较高覆盖率,程序员们需要给定多次输入进行多次试跑才能达到比较好的效果。这一下可就让软件开发者社区彻底撂挑子了,而编译器又不能自己推断出每个程序需要的数据输入是什么样子,于是剖析在开发实践中被冷落也就情有可原了。除此之外,剖析作为编译优化的一种,也有着每一项编译优化技术都有的难言之隐:编译一般只进行一次,于是优化机会只有一次,宝贵的唯一一次。

  如同人在少年青年壮年老年时的身体状况,程序执行的整个生命周期中出现多个特征明显不同的阶段是常有的事,为每一个阶段选择最优的优化策略是最好不过的。但尴尬的是,编译只能进行一次,经过编译以后,二进制代码就完全固定无法再更改,即便编译器在试跑中观察到了同一段代码上有多种不同的特征交替出现,也只能为其中一种情况做优化,若要动态地调优,编译器就必须获取这样一种能力:在程序出现一种特征时,收回已经编译好的这段代码块,替换成功能相同但是为这种特征专门优化过的代码块,然后继续执行。这种能力在静态翻译和静态编译的框架下犹如痴人说梦,而动态二进制翻译则不然,执行一段代码翻译一段代码的基本法则本来是它的阿喀琉斯之踵,此时却转变成了斩杀静态二进制翻译的伊兰迪尔之剑。每一次执行代码时动态二进制翻译都有机会重新调起翻译器,因此优化策略可以随着代码特征不同随意改,这令它与一众编译剖析优化技术形成天作之合,静态二进制翻译下受限于运行时信息的缺乏而无法有效完成的优化,在动态二进制翻译的框架下全部成为可能,而动态二进制翻译与剖析的结合所形成的动态剖析技术还自然而然地顺手解决了剖析优化需要程序输入的难题!

  这个一箭双雕的idea的成形是否出自全美达“漂流者”的独立工作,现在已经难以验证,全美达公司挣扎几年之后终究未能达到外界预期,被Novafora公司收购。回顾这段历史时我们唯一确信的,是这个idea的力量与其他设计考量一起,令全美达这位先驱者走向了一条独一无二的软硬件协同设计的道路。为了进一步挣脱编译时优化的桎梏并提高二进制翻译性能,全美达从一开始就为“漂流者”选择了超长指令字(VLIW)结构。这是一条与主流微结构平行,经历了多年的研究和工业实践之后在通用处理器市场上仍未收获广泛认可的结构,为什么全美达会青睐VLIW,VLIW又为何在通用处理器市场上缺乏建树呢?

  失败的挑战者:VLIW

  纵观Intel、IBM、AMD、ARM,以及曾经的DECAlpha、MIPS等各大芯片巨头,他们所推出的现代高性能处理器,几乎全部基于上世纪60年代CDC6600的记分板算法与IBM360/91的Tomasulo算法发展起来的框架所搭建。硬件控制下的分支预测→取指令→解码指令→寄存器重命名→指令分派/乱序发射→重排序缓冲区→顺序回退,这一套框架俨然铁桶江山,在近三十年的时间里没有发生一次颠覆性的变革。这从侧面说明了硬件主导的多发射乱序执行框架的性能优势已经相当稳固,同时也说明其他派系的微结构例如数据流结构等,在兼容性、开发/迁移难度、绝对性能、绝对功耗乃至性能功耗比等指标中存在至少某些短板,使得现今的硬件乱序多发射框架得以逐步发展直至完全定形。但在这三十年时间里,硬件乱序多发射框架的地位也并非完全稳固,迄今为止声势最大的挑战者大概是Intel和HP联手推出的Itanium。

  Itanium的主要设计出发点之一是,硬件控制下的乱序多发射指令调度非常复杂而且功耗较高,如果能把主要调度工作交给软件在编译时解决,依靠编译器来发掘出同样多的指令级并行度,硬件的设计上就能简化许多,甚至完全卸下调度负担,从而降低设计复杂度和功耗。与它基本同期诞生的全美达“漂流者”采用VLIW的原因也大致如此,只是全美达在软硬件协同设计,特别是动态剖析上考虑得比Intel更远一层。由于概念相对新颖,而且背后站着Intel与HP两大靠山,Itanium的首轮进攻声势浩大,Intel直接为Itanium所使用的指令集起名IA64,寄望于用这个全新的芯片击败AMD等竞争对手,确立64位指令集的事实标准,业界著名市场调研机构IDC也对Itanium期望甚高,豪言Itanium服务器将有380亿美元的销售额。

  然而第一代Itanium问世后,其实际表现令业界大跌眼镜,性能相比同时期的Pentium4落后幅度之大已经到了令人瞠目结舌的地步,由于Itanium的指令集与x86不兼容,只能依靠二进制翻译执行,在某些Benchmark上,二进制翻译之后的代码执行速度居然被石器时代的486击败。尽管Itanium2的性能相比前代一口气翻了四倍,但是浮点性能仍然落后于同时期的Power5,整数性能也落后于同时期的Pentium4。雪上加霜的是,Itanium的设计复杂度和功耗却不降反升,随着VLIW理念所期许的设计复杂度与功耗优势化为泡影,IDC也越来越心虚,不得不一次又一次地调低销售预期,最后Itanium服务器的实际销售额尚不足初始预期值的二十分之一,几成业界笑谈。由于Itanium的孱弱,AMD用自己的64位指令集牢牢掌握了64位时代的指令集先机,Intel不得不罕有地向AMD低头,AMD64这个名字被许多开发者采用,写进了他们的软件项目当中作为64位指令集的民间非正式名称,而Intel的Itanium也写进了鼎鼎大名的《量化研究方法》作为典型失败案例分析。

  回天乏术,“基本不可能写出那样的编译器!”

  公平地说,Itanium所代表的VLIW流派并非一无是处,在研究VLIW的过程中催生的一些优化策略,特别是编译器优化方面,得到了后继者的传承。如果没有Itanium和其他VLIW结构上的研究与工业实践,人类对编译器与软硬件协同设计的认识和理解就不会有今天的高度。但是,Itanium的一败涂地极大地损害了二进制翻译与VLIW的形象,更加巩固了硬件乱序执行的主导地位。计算机科学界泰斗DonaldKnuth在2008年接受采访时炮轰体系结构研究错误走向了多核心方向,顺带地就把Itanium踩了一脚:“基本不可能写出那样的编译器!”

  DonaldKnuth的担忧不无道理。Itanium微结构的设计与全美达”漂流者”一样,受到编译器能力的极大影响和制约,几乎整个微结构上的细节信息都开放给了编译器,许多地方还加上了推测性标记来帮助编译器实现激进的推测执行来缩短与硬件乱序调度的性能差距,但饶是如此,编译器的能力仍然不足以完全信赖,Itanium不得不加入了硬件负责控制的分支预测和寄存器重命名、记分板等部件。严格来说,从这一时刻开始,Itanium就不再是纯VLIW结构了,而是一个糅合了VLIW与硬件乱序调度二者特征的怪胎,在编译调度能力跟不上的情况下强行将主要调度工作转移给编译器,同时不顾主频和功耗上的倒退强行将后端执行宽度提升,最后又引入硬件调度作为补救,设计复杂度不降反升也就可以理解了。DonaldKnuth的话实际上也代表着体系结构研究社区内相当一部分人的看法,相比硬件乱序调度来说,编译调度的孱弱已经回天乏术,随着指令级并行度热潮的冷却,这一话题关心的人越来越少,对VLIW这种由编译主导的微结构的怀疑也就随着时间的积淀而固化下来。在Itanium之后十年,尽管一些有关VLIW的研究项目仍在进行,但是市场上没有任何一种主流处理器采用VLIW结构,硬件乱序多发射的执行框架已经是事实上的唯一选择。

  NVIDIA:“微结构的未来在于动态剖析”

  Itanium在主流市场上失声之后十年,VLIW派系的微结构再也没有向主流市场发起成建制的进攻。直到2014年初,NVIDIA在CES大展上第一次向外界透露丹佛计划主角—Tegra K1的技术细节,业界震动。PPT上的“7-waysuperscalar”(七路超标量)关键字曝光以后,一些IT评论家敏锐地意识到NVIDIA很可能使用了VLIW来实现这样的执行宽度,随后关于动态二进制翻译、前全美达团队成员介入开发的猜测也甚嚣尘上。

  到了今年8月,从Stexar入职NVIDIA的前Intel架构师DarrellBoggs现身Hotchips大会向业界介绍Tegra K1的微结构,这些猜想才得以最终确定,只是二进制翻译的目标指令集从x86变成了ARM。尽管PPT和宣传文稿上并没有明确出现VLIW的字样,但是整体微结构框架中所使用的理念实际与我们在上文中介绍的如出一辙:动态二进制翻译、动态剖析、编译控制的乱序执行(VLIW),并且其核心创新动态代码调优技术身上能看见一些当年全美达“漂流者”的影子。由于软件调度的优势,在VLIW上做到七路超标量根本不稀奇(Itanium曾做到12路),对于Tegra K1来说,意义最大的并不在于执行宽度。Itanium在主流市场上失声十年之后,NVIDIA选择让Tegra K1再度以VLIW+动态二进制翻译的面貌重回主舞台,抛弃了成熟的硬件乱序执行框架,这一选择背后的意味才是最耐人寻味的地方。

  如果不出意外,Tegra K1将会是此后NVIDIA在移动SoC上的拳头产品,Tegra K1应该会是继Itanium之后另一个出货量级相对较大的VLIW芯片。对于NVIDIA来说,推出这个芯片就是一场赌博,背离主流微结构已经铺好了三十年的硬件调度路线,再度选择通用处理器市场上不被看好的VLIW,是不是有什么特别的考虑?

  尽管通用处理器市场上VLIW遭遇惨败,但是VLIW的设计理念在嵌入式低功耗市场上却受到青睐,简化硬件设计降低功耗,由软件来发掘指令级并行度,刚好与嵌入式低功耗市场的需求不谋而合。加上动态二进制翻译层的介入,传统VLIW所面临的编译尴尬也得到了解决。底层硬件结构更新以后,只需要更新翻译器这一层软件即可,可以通过打补丁之类的方式实现,不再需要对所有程序全部重新编译,就能享受到新结构带来的好处。

  写在最后

  截止目前基于丹佛架构Tegra K1处理器的机型还未量产上市,因此性能方面的测评还为时尚早。新的动态二进制翻译器会引入多大的性能开销,Tegra K1的底层硬件如何与动态剖析器进行软硬件协同设计,动态剖析器收集了哪些程序特征信息,做出了哪些优化,实际表现是否会如NVIDIA在PPT上宣称的那么好,仍是未知数。但就NVIDIA脱离成熟道路而勇敢选择VLIW+动态二进制翻译,将动态剖析大胆引入主流微结构这一做法来说,是非常值得赞扬和鼓励的。如果Tegra K1表现给力,它将有机会重新改写教科书上对VLIW派系的评价,重新定义一种新的微结构发展方向。从这个角度上来说,Tegra K1芯片的设计决策所关系到东西远不止NVIDIA在移动SoC市场上的盈利与胜败,从更长远的部分来说,它也代表着沉寂已久的VLIW派系再次对硬件乱序执行的传统框架发起一轮新的冲击。

……
关注读览天下微信, 100万篇深度好文, 等你来看……
阅读完整内容请先登录:
帐户:
密码: