来,战个痛快
前言:GPU大百科全书系列的连载已经进行了4期了,在这4期的连载中,我们领略了GPU流水线在处理图形过程中的前三步重要步骤,包括几何处理,光栅化和像素处理。尽管笔者竭尽所能将故事说的尽可能通俗易懂,但是在水平有限,因此笔者在这里再次诚挚的感谢能够坚持阅读的读者们。在本期的GPU大百科全书中,我们将会以一个全新的视角,来面对一系列长达10年之久并还在继续的关于设计之争的大论战。
也许你会觉得,技术的进步和产品的分歧只是一场很热闹的游戏,除了昭示某方看似一念之差所犯下的错误以及给各种争论带来弹药之外,好像并没有别的意义,我们这么反复咀嚼吵架剩下的东西一点意思都没有。
其实不然,10年来NVIDIA与ATI/AMD在shader领域相关的IC设计之争以及此消彼长,其本质上并不是,或者应该说不仅仅是各公司自身设计实力所导致的。到底是什么导致了这场长达10年的纷争中的每一次胜负?这些胜负又意味着些什么?这种导致胜负的因素会不会对今后的继续影响GPU的发展?我们在今天的GPU大百科全书所要解析和面对的,就是这存在于喧哗吵闹背后的真实。
● 来,战个痛快
NVIDIA与ATI,以及后来收购ATI的AMD,这对冤家的恩怨纠葛几乎伴随了整整一代人的成长。自从3Dfx,S3,Trident,Matrox以及SIS这些曾经叱咤风云的图形大鳄们退出历史舞台之后,NVIDIA和ATI/AMD就完全霸占了IC舞台中最抢眼的一部分。
在先前的文章中,我们仅仅使用了最程式化的流水线介绍法来展现相关单元的运作方式以及技术特点,并未涉及任何实际的产品。对于几何部分以及光栅化这两个相对封闭而且更新节奏较慢的单元来说,这么做不仅能够避免把话题过早的引向争论,而且可以消弭差异化所带来的理解方面的问题。但当我们的来到像素处理部分时,这对冤家在设计上的差异已经非常表象化,而且到了完全无法忽略的地步。伴随着像素处理单元发展的,是一场又一场惊心动魄的战争。
既然不能忽略,那就让我们直面这份差异。来,战个痛快!
顾杰所写过的技术分析类文章索引(持续更新) | |
2、 忠实微软是否有用 A/N统一构架细节分析 | |
3、揪出幕后罪魁祸首 是谁拖累了统一架构 | |
5、融聚的未来在哪里 APU构架方向发展分析 | |
7、NV也玩融合 探GTX700核心CPU+GPU构架 | |
11、iPad2也成无尽陷阱?移动GPU构架全揭秘 | |
13、GPU大百科全书第一章:美女 方程与几何 | 14、重归正途迎未来 AMD新GPU构架深度解析 |
15、GPU大百科全书第二章:凝固生命的光栅化 |
● 第一次争论
shader的第一次出现,对任何人来说都是欢欣鼓舞的事情,可以实现各种过去想都不曾想过的特效不仅让程序员们兴奋不已,更令硬件供应商摩拳擦掌——这下好了,又有敦促消费者升级以及更换硬件的完美借口啦。
当然,光有借口是不够的,厂商必须设计出实际的产品,才能最终让消费者打开荷包任其舔舐。而设计产品就要有计划和设计目的,产品必须符合一定的要求和规范才能成为产品。对于图形供应商来说,规范和要求似乎没啥可选择的余地,满足DirectX和Open GL似乎是唯一的要求。无论怎么看,这本来都应该是挺简单的一件事。
但是活雷锋大商人微软是顽皮的,他似乎并不喜欢让一切都如剧本般一帆风顺的进行下去,于是便为这个本来应该是挺简单的事情添加了一份变数——在发布包含Pixel Shader1.0/1.1的DirectX8.0之后1年,微软又发布了升级后包含Pixel Shader1.4的DirectX8.1。
相对于Pixel Shader1.0/1.1,Pixel Shader1.4的改进其实并不明显,除最大指令支持度上进行了升级之外,Pixel Shader1.4并未带来更多实质性的进步。但即便仅存在些许的进步,毕竟他是微软发布的一个新版本API,游戏规则的改变势必会影响到厂商对硬件设计层面的决策和部署,如果某个硬件对于新的API支持不足,厂商就要对市场作出解释,以当时的情况来看,第一个需要作出解释的厂商,是NVIDIA。
NVIDIA于2002年4月发布的NV25并不支持的Pixel Shader1.4,这款新构架虽然效能卓越,但其API支持度甚至还不如半年前竞争对手ATI发布的R200,这种奇特的现象不仅让市场无法理解,而且也让竞争对手抓住了小辫子。NVIDIA给出的对NV25不支持Pixel Shader1.4的解释是Pixel Shader1.4改进极少且响应欠佳,在没有获得多少支持度的前提下推出对应的硬件没有意义。说白了,就是Pixel Shader1.4现在还没用,我们的新构架满足有用的API的需求就可以了。
以现在的眼光来看,NVIDIA在当时所作出的宣传其实并没有错,Pixel Shader1.4本身的更新确实不大,而且也并未带来本质性的特效提升。经营了1年半之久的Pixel Shader1.0/1.3在当时已经获得了非常好的支持度,推出适应的硬件其实也没有错。从结局来看,NV25也确实因为其强劲的性能、灵活有效的市场划分和对手各种糟糕的表现而获得了几乎完胜的销售成绩。可以说第一次针对硬件的争论,是以NVIDIA的胜利而告终的。
尽管这场并不算很大争论最终的胜利属于NVIDIA,但同时也给NVIDIA传达了一个相当错误的信号:NVIDIA误以为自身的影响力,已经可以凌驾在舆论以及微软之上了——既然我说Pixel Shader1.4暂时没用,市场就能接受这种言论并且很自觉的买我的帐,那这块市场岂不是我说了算了?这个错误的信号,为今后故事的发展埋下了一个巨大的伏笔,它直接导致了NVIDIA在未来第一场真正的战斗中犯下的其发展史上最大的一次战略错误。
● 有关精度的唇枪舌剑
如果说Pixel Shader1.4之争仅仅是支持度的问题的话,接下来所发生的这场争执就不再那么简单了。它不仅将NVIDIA与微软的分歧摆上了台面,更影响了NVIDIA整整一代产品的表现,它就是初代DirectX9.0的浮点精度。
2002年12月,微软发布了全新一代图形API——DirectX 9,如果说DirectX 8.1的Pixel Shader1.4改动来的太小,支持度和意义都不是很大的话,DirectX 9的Pixel Shader2.0就可谓是脱胎换骨了。全新的Pixel Shader2.0所引入的更大的指令数也让Pixel Shader2.0获得了更好的效率,同时FP24浮点格式的RGB数据处理让程序员第一次有了能够完整正确的表达颜色的可能。有了DirectX 9,人们终于有可能在计算机上创造“虚拟的现实”了。
但就是这么一个重要的API,却在发布的同时就引发了一场巨大的争吵和骚动。人们纷纷对微软使用的浮点精度表示了困惑,而NVIDIA则第一时间对这种精度提出了质疑,认为这个浮点精度是不会被市场采纳和接受的,得不到认可的,更将矛头直指微软针对自己,恶意推出一款违背常规及现实需要的图形API,我们甚至可以从当时NVIDIA的态度中感受到明显的激动。
也难怪NVIDIA如此激动,因为美国电气和电子工程师协会在IEEE 754中规定的二进制浮点算法规则里,压根就不存在FP24这么个格式……
根据硬件的预研周期,一款图形构架是不可能等到图形API出现之后才开始研发工作的。因此对于厂商来说,如果想定义一款构架所需要遵循的基本规则,要么厂商要自己对即将到来的API内容进行预判,要么通过与规则制定者的紧密合作来获取规则的第一手资料。虽然没有人只用一条腿走路,但在第一代DirectX 9硬件的研发过程中,NVIDIA很明显更倚重于前者,而ATI则明智的选择了后者。因此后续出现的NV30所支持的浮点精度均为IEEE754规定的FP16/32,而R300则紧贴微软的要求,刚好支持FP24这个并不存在于国际通行标准中的格式。
相信DirectX 9发布时的NVIDIA,心中一定是充满了疑惑、愤怒和不安的,因为他十分清楚接下来将要发生的事情。而像素处理单元战争故事中第一个高潮,也即将到来了。
● 小小寄存器+狂妄引发的大败
业界很少有一款产品,能够像NV30这样在与对手的战争中输得如此的彻底。性能不佳,良率低下,价格昂贵,功耗巨大,甚至还得了个电吹风的头衔……对NV30的失败,很多事情都要出来负责,比如说低速的DDRII显存,过激的工艺,甚至还有微软“特异”的浮点精度。但这些都不是导致NV30失败的本质,如果你想明白NV30为何会如此惨败,以及这失败背后的真正含义,就要从NV30的Pixel Shader单元设计寻找答案。
享有电吹风“美誉”的Geforce FX 5800Ultra
NV30的Pixel Shader单元设计存在很多独特的特点,它并不具备Pixel Shader2.0中很常规的处理3D+1D以及co-issue的能力,如果遇到坐标变换等需要非绑定4D运算的场合,NV30将一筹莫展。与此同时,NV30的Pixel Shader单元还不具备mini ALU,shader core后面吊着的,是两个完全符合DirectX8.1要求的FX12 combine,由于Pixel Shader2.0并不支持混合精度以及非浮点精度指令,所以这两个FX12 combine单元在DirectX 9的场合中完全就是废物。尽管后续的NV35添加了2个可以吞吐FP16/32的mini ALU,但这两个mini ALU并非全功能,在大多数场合下都进能运行在simplified模式下,说白了,加了等于白加。
问题还没完,NV30不光运算单元设计成这样,寄存器方面也存在极大的问题,甚至可以说寄存器的设计失败才是最为致命的。整个NV3X构架的Temp Register被限定为13个,仅比Pixel Shader2.0所要求的12个的最低要求多1个。Register被分为2个bank,这2个bank加在一起每周期内只能向shader core输送一个FP32或者两个FP16数据,由此造成的延迟是异常巨大的。在此基础上,本来就不够多的Register还要被拿去做Output Buffer,或者说Register与Output Buffer使用了同一片存储区域,如果某个shader Program的数据需要调用2个FP32 Register或者4个FP16 Register,NV3X的整体渲染效率就会开始大幅下降,这种下降还会随着调用寄存器的增多而不断加剧,当FP32 Register调用达到5个时,整个流水线的像素填充率只能达到理论值的1/4。
NV30被设计成这样,那他的对手R300呢?完整的3D+1D shader core和3D+1D mini ALU,尽管这些ALU的精度仅支持FP24但却完全符合微软的要求。32个Temp Register也让它完全可以大声地嘲笑寄存器资源极度不足的NV30。我们在R300身上看到的是充满了流畅和简洁的数学美感,而在NV30身上,我们只能看到非常全面的缺点和失败……
究竟是什么原因导致了NV30采用如此不堪的设计呢?其实答案很简单——如果你把NV30看成一款具有优秀DirectX 8.1性能,同时兼顾DirectX 9.0性能的GPU,一切就都了然了。
前面我们提到了,Pixel Shader1.4那场争论向NVIDIA传达了一个错误的信号,让他误以为自己已经强大到可以左右市场并正确预判未来的一切。这虽然并没有直接导致NVIDIA与微软的交恶,但也让NVIDIA在与微软的后续合作中表现的远不如ATI积极。按照NVIDIA的设想,由于初代shader的成功,市场能够接受和消化的更新速度以及节奏,只能允许下一代API在尽可能保持传统版本特色的基础上做出些许改进。同时,微软既然在DirectX Next Preview中宣布了新的Shader Modle会引入浮点型数据,那么符合IEEE 754规定的FP16/32格式将很自然的成为微软的选择。于是,一款“保持传统版本特色”同时做出“些许改进”以便支持新版本特性的图形构架,就这样来到了我们面前。
反观ATI,收购了ArtX让ATI的图形设计迅速的成熟了起来,与微软的紧密合作也让他能够第一时间获得新版本DirectX的所有信息,这种合作的紧密最终甚至发展到了足以影响微软决策的地步——我们实在无法解释为何微软会冒巨大的风险,来选择使用一个并未被IEEE组织承认且本身有没有任何特别的好处的浮点数据精度,更无法解释这种精度在接下来的一次小升级中即被替换的结局。如果你无法接受这一切均来自ATI的影响的话,那就只有虚构一个更加强大的“外部势力”来进行干预了。
总之,像素处理单元的第一场真正的大战,也就是精度战,至此已经分出胜负了。在这场战斗中,NVIDIA所犯下的一系列错误并非来自研发实力的差异,他只是为自己那几年的狂妄或者说自我认知不足,以及对时局的把握不当付出了代价。
● 潜伏在黎明之前
我们在前一篇GPU大百科全书中曾经提到过,除了精度战之外,像素单元的发展中还曾经发生过谍报战。谍报战?你以为NVIDIA是峨眉峰,ATI是佛龛么?开什么玩笑,几个ALU单元的设计,还能闹出谍报战这么玄乎的东西出来?
能,不仅能,而且异常精彩和成功。
CeBIT2004上NVIDIA的一系列情报战,让这届展会声名鹊起
还记得CeBIT2004上那个“完美支持DirectX 9.0,8条流水线,每条流水线2组TMU单元,单周期能够进行16次浮点像素操作及贴图操作,特别包含来自3Dfx未发布的rampage所使用的先进技术”的“NV40”么?这个看上去像是NV35放大一倍,同时有火星科技加持的东西几乎欺骗了全世界,不仅包括竞争对手ATI,全世界所有的玩家以及关注者,投资家,股评人,甚至还包括一部分尚未得到芯片的显卡厂商。4月之前,ATI不紧不慢的维持着自己R400系列的研发工作,整个世界则几乎都在热火朝天的讨论着3Dfx这个曾经的图形帝国,在崩溃之前究竟留下了怎样的黑科技,甚至黑到可以帮助弱到不行的NV3X去争夺性能王座。而关于这个构架本身的真实度嘛……
至于你信不信,我反正信了。
在经历了NV3X的溃败之后,颜面尽失且市占率受到冲击的NVIDIA十分急于收复失地,重新确立自己图形霸主的地位。有介于NV3X的失败,他必须快速的,起码是比竞争对手更加快速的推出一款改进型构架,在抢得发布先机的同时重新赢回性能王座。又要发布快又要性能快,最最大的可能就是把NV3X的规模各种放大,然后以新工艺+高频的形式快速放出。这一点你知道,我知道,ATI知道,所有人都知道。
所以,我们就都被骗了。
NVIDIA成功的抓住了包括竞争对手在内的所有人的心理,让所有人都认为自己会为了短期效益脑袋发热的去继续走NV35缝缝补补的老路。这不仅极大地麻痹了竞争对手,同时也为后来的NV40上市创造了破纪录的惊喜感。因为它太过出乎意料,太过超越人们设想的底线,甚至几乎完全站到了NV3X构架的对立面上,成了先进高效构架的典型。
相对于NV3X,NV40的改进可谓大刀阔斧。它彻底去掉了只属于DirectX 8的Combine,代之以具备完整功能mini ALU且支持co-issue的shader Unit 2,完全修正了愚蠢的Register bank问题、Output Buffer与Register使用同区域以及极少Register总量的错误,NV40构架可以做到同时调用4个FP32 Register或者8个FP 16 Register,像素填充率仍然不出现下降。有了这些改进,再加上整体放大的规模,NV40的各方面性能均可以达到NV35的2倍以上,在很多DirectX 9类得场合甚至可以达到4倍以上。与此同时,NV40还完整支持了全新的DirectX 9.0C。Shader Modle3.0的地位和意义我们在以前的文章中曾经反复强调过了,NV40作为业界第一个完整支持它的构架,其意义可想而知。再加上IBM fishkill fab亲自操刀带来的130nm铜互连工艺以及冗余晶体管设计等等耀眼的光环,可以说NV40一出,全世界瞬间便为之疯狂和兴奋。
当然,除了一个人之外,那就是ATI。
之所以说NVIDIA在NV40上发动的谍报战是成功的,相当大一部分原因在于他成功的麻痹了竞争对手ATI,这种麻痹甚至过于成功,成功到拖慢了竞争对手的研发速度的同时让对手彻底乱了节奏。
NV40的发布让ATI陷入了空前的尴尬和窘迫之中,因为根据之前多方面汇总的情报,ATI已经做出了确认NVIDIA要推出“完美支持DirectX 9.0,8条流水线,每条流水线2组TMU单元,单周期能够进行16次浮点像素操作及贴图操作,特别包含来自3Dfx未发布的rampage所使用的先进技术”的新构架的判断,同时将自己完整支持DirectX 9.0C的R400构架的研发速度控制在了一个相对缓慢的程度。R3XX的成功让ATI充满了自豪和满足感,这种自豪和满足感最终发展成了过度的自我膨胀以及对对手的轻视。NV3X的设计不足以对R3XX构成威胁,那么在此基础上进行的修补自然也就不会对R3XX构成威胁,更不要说更加先进的R400了。
可是谁都没想到,最终到来的NV40,却是这么个大炸弹……
根据预研周期判断,我们有理由相信ATI并不是在NV40发布当天才获知其真面目的,因为一款构架的研发不是过家家,说上就能上。但我们同样有理由相信,NV40的确在相当长的一段时间内成功的欺骗了ATI。在NV40发布前后,陷入巨大慌乱的ATI彻底乱了阵脚,本来计划中利用R350的结构基础+支持DirectX 9.0b,用来对付那个不存在的软弱对手的构架显然不能应付目前的局面了。ATI不得不紧急停止了一切原计划的R400的研究工作,转而将先前的改进型构架放大规模到与NV40同等规模,同时尽可能多的提高频率,以便让其获得与NV40抗衡的可能。至于DirectX 9.0C,那实在是没有办法说上就上了。于是在NV40发布后,我们又看到了似曾相识的一幕——ATI站出来反复强调和攻击DirectX 9.0C,称其是不合时宜以及缺乏支持度的。
在第三代像素处理单元的战争中,胜利者毫无疑问是NVIDIA,仓促上阵的R420虽然得益于R3XX的优秀基因而具备了不错的Shader Modle2.0性能,但相对于NV40来说,在效能上始终乏善可陈,而且缺乏对Shader Modle3.0的支持让其注定无法与NV40同场竞技。像NV30时代的NVIDIA一样,ATI输了,而且连输的理由都跟先前NVIDIA的一摸一样。
也许你已经注意到了,尽管像素处理单元的设计之战精彩纷呈而且花样翻新,但似乎胜负的决定要素都是一样的,而且这个要素,跟绝对研发实力似乎根本没有关联。
● 一代天骄
其后的几年时间里,故事的走向似乎有些乏味。由于DirectX 9.0C的快速普及,以及其本身的完善所带来的更长的更新周期,无论NVIDIA还是ATI都有充足的时间和空间陆续成熟和完善着自己的构架。ATI从最初的慌乱中镇定下来之后,将原本的R400重新设计成代号Fudo的R520,由于NV40的成功,R520好像并没有达到“扬眉吐气”的级别,甚至还遭遇了IC工艺史上第一次深亚微米屏障带来的制造问题——吸湿和孪晶。而NVIDIA则将NV40进一步完善成了G70,同样由于NV40的成功,人们觉得G70本来就该是这个样子,没什么值得高兴的。
尽管从NV40到G70,NVIDIA继续玩了一把谍报战,在产品代号的突然转变上又坑的ATI冒了一身的冷汗。但由于DirectX 9.0C本身的限制,G70相对于NV40仅仅是完善和进一步拓展规模,因此ATI并没有像上次那样遭遇严重的尴尬。R520和G70在结构上也开始有了不小的趋同倾向,像素处理单元领域仿佛陷入了一篇沉闷之中。还好,这种乏味并没有持续很久,相对平静的生活在持续了1代产品周期之后被打破了。
因为一代天骄来了。
一代天骄R580
在Shader Modle3.0时代末期,人们开始思考即将到来的未来究竟需要怎样的硬件。尽管新的DirectX Next Preview泄露出了一定的关于微软未来在图形领域的规划方案,比如说Unified Shader,但这仅仅是对于shader执行的一个细节而已,真正影响未来走向的新版本API的灵魂,或者说强调的方向并未被众人所知。Shader Modle3.0强调的是长到近乎无限的指令长度,以及由此引发的更加庞大的Pixel Shader Program数量,那Shader Modle4.0所要强调的又会是什么呢?
ATI站出来大声说——我知道了!是吞吐!
如果以常规的眼光出发,由于Shader Modle3.0的成功,顺应强调指令长度以及更庞大Shader Program数量的做法势必会为Shader Modle3.0的应用带来更好的性能,所以吞吐在当时来看是一个非常不错的选择。而按照这种眼光,微软也会尽可能多的在新版本的Shader Modle中照顾旧有版本的特色,因此吞吐必定会是下一个版本的Shader Modle所要强调的方向之一。于是,为了给这条道路积累经验,同时为了让当下的Shader Modle3.0产品更具竞争力,ATI完成了被誉为“一代天骄”的R580的研发。
作为R520的继任者,R580拥有了Shader Modle3.0时代唯一的一次构架突破,他将传统的每个shader unit的ALU体系数量原先的1个提升到了3个,这一改动让R580在流水线总数不变的前提下拥有了3倍于R520的Shader Program吞吐能力。这种构架的绝对性能在当时是相当恐怖的,其对手G71尽管拥有更多的流水线和co-issue能力,但都不足以弥补绝对像素处理能力的差异。R580的构架设计赢得了所有人,尤其是程序员们的一致好评,它带来了极其强劲的Shader Modle3.0性能,同时也满足了当时通过更多像素效果来提升整体视觉效果的诉求。R580获得了胜利,成了Shader Modle3.0时代当之无愧的单芯卡皇,在一片溢美的赞誉之声中,3:1“黄金构架”的一代天骄将ATI的声望推向了顶峰。
可笑的是,这种溢美的赞誉和承认以及性能的胜利,跟不太久的过去里发生的另一次胜利一样,向获胜方传递了一个非常错误的信号——我真的好强大,强大的我说什么就是什么,我可以预言未来,掌握一切,I'm the King of the World!
呵呵,难道你不觉得这一幕非常眼熟么?拜这种眼熟所赐,又一段精彩的胜负大战即将上演。尽管命运仿佛早已按照某个非常幽默的程式将剧本写完了,但这并不妨碍我们来欣赏一下这一幕注定结局的情节。
● 另一种狂妄引发的大败2.0版从R580到R600,这中间发生了许多的事情。在那个即便强调吞吐,效率的提升也依旧会被分离单元设计吃掉的年代,R580尽管理念先进但却着着实实的赢了面子输了肚子。它为效率提升付出了巨大芯片面积的代价,最终的效率却被非统一单元低下的运作率无情的吞噬。后来,ATI被AMD收购,AMD继承了ATI全部的遗产,这其中也包括了R600。
业界很少有一款产品,能够像NV30这样在与对手的战争中输得如此的彻底。本来我们以为NV3X的经历可以让整个业界记住教训,今后很难会再出现超越NV30的失败了,但R600却非常坚定的打破了我们的观点……
同NV30一样,很多事情都要站出来为R600的失败负责,比如说慢如公共汽车的ringbus总线,充足但却各种受制并最终变得羸弱的后端设计,还有对GDDR4不正确的热衷。但同样和NV30一样,这些都不足以成为最本质的罪魁祸首。真正导致R600大溃败的原因,依旧来自像素处理单元的设计问题。
R600采用VLIW捆绑的4D+1D结构,4个非全功能1D ALU和1个全功能4D ALU以捆绑的形式构成一个SIMD US处理单元,所有单元公用US的发射端口资源。这种设计可以带来极大的理论吞吐能力,但同时要求若干条指令以VLIW的超长指令形式统一进行吞吐,才能发挥出全部ALU的运算能力。这种强制的要求不仅对驱动和编译器提出了极大的要求,而且要求程序段必须让指令之间尽可能的不存在任何关联性。如果指令A与指令B存在条件分支,指令B需要指令A的结果作为初始判断条件,而这两个指令又非常不幸的凑巧或者不得不被打包成同一条超长指令,那结果就是灾难性的。指令A和指令B一同进入了US单元内部,指令B必须等待自己和指令A一起跑完US单元内部全部的寄存器和运算单元才能出来,而且由于条件分支关系,指令B在这一整个过程中实际上是什么都做不了的,他必须徒劳的经历一次打包过程,进入一次US,经过完整却无意义的过程之后从US中出来,再经历一次解包过程,等待指令A释放执行结果,然后再经历第二次打包过程并回到US中进行处理。如果遇到多重条件分支,这个灾难性的过程还将被重复数次。
如果仅仅吞吐这么麻烦,那倒也不是什么可怕的事,我们可以通过优秀的缓冲和并行机制设计来充分的掩盖这部分由VLIW产生的延迟。但糟糕的是R600的缓冲机制就如同NV30的寄存器设计一样,无厘头到不可理喻的地步。R600仅为全部的VLIW US单元提供了8K的GDS作为临时数据的缓冲,而且由于驱动以及对缓冲机制本身作用的理解不足所导致的设计缺陷,对于GDS的实际操作长期以来一直都是一件极度困难的事情。VLIW导致的高延迟,无法发挥有效缓冲作用的缓存体系,再加上为了照顾吞吐而被定义的过大的线程粒度,这三个蹩脚的搭配造成的结果,让R600拥有了极端低下的shader灵活度。在某些特定的线程粒度下,R600的整体体系延迟,甚至可以超过竞争对手G80几十倍!
跟NV30 VS R300一样,要明白R600的core和uncore部分设计的问题有多严重,我们自然也要设立对照组——G80虽然在整个运算单元集群的角度来看也属于SIMD结构,但每个基本ALU团簇单元,也就是SM所采用的则是更加灵活的MIMD设计,对于指令的吞吐不存在打包以及关联性的限制。G80的每个SM都拥有独立且面向单个ALU开放的8K shared memory作为缓冲,相比于R600的320个ALU一起抢8K GDS的状态,G80的SP(ALU)单元简直就是处在天堂一般。多样化且灵活的吞吐方式,巨大且十分有效的缓冲体系,以及更小的线程粒度,让G80完全站在了R600的对立面。我们在G80身上看到的是充满了流畅和简洁的数学美感,而在R600身上只能看到非常全面的缺点和失败……
什么?你说你有了即视感?感觉好像在哪里见过这句话?放心,那不是错觉,在NV30对战R300时,我们曾经说过一摸一样的话。现在,历史轮回,一切都被以几乎完全相同的形式重演了。
既然历史以相同的形式重演了,那导致R600失败的原因,会不会也跟着非常欢乐的重演一次呢?没错,会的——如果你把R600看成一款具有优秀DirectX 9.0C性能,同时兼顾DirectX 10要求的GPU,一切就都了然了。
AMD在R600身上所要强调的是ILP,也就是强悍的吞吐能力和单位指令执行能力,这种能力在Shader Modle3.0时代是非常重要的。如果把R600身上对应DX10的特性都去掉,并用这些节省下来的晶体管稍微强化一下总线以及材质单元等领域,然后早出1年,R600便可以摇身一变,成为一款强悍到令全世界震惊的怪兽级显卡。之前一代天骄在性能上的成功,让ATI跟当年的NVIDIA犯了几乎一摸一样的错误,令其对Shader Modle4.0的方向进行了错误的预估,同时也失去了同微软原本十分紧密的联系。甚至因为程序员对R580设计的赞美太过真诚,ATI产生了一个致命到几乎可以说精神失常的错觉——我ATI可以通过强大的影响力直接影响程序员,不管未来的Shader Modle发展成什么样,只要我设计出了自己觉得合适的硬件,就可以迫使程序员就范,从编程的角度来迁就我的硬件设计方式。
再来看NVIDIA,在经历了NV3X的教训之后,汲取了丰富经验的NVIDIA放下了几乎所有的架子,全天候的跑去跟微软跳起了暧昧的贴面布鲁斯。这种与规则制定者的紧密联系让NVIDIA在第一时间获得了足够的新API的信息,并根据这些信息正确的判断了Shader Modle4.0将会从传统的强调吞吐转向强调灵活shader应用以及逐步并行化的发展方向。其实无论ATI/AMD还是NVIDIA,其整体设计水平虽然确实存在差异,但却绝对没有达到足以致命的地步,因此决定胜利方的要素,几乎就是在预研过程中对未来方向的判断和把握。谁掌握着正确的方向,谁就能够在竞争中胜出,而如果双方的方向都没有错误,那必然会带来殊途同归以及平淡的结局。
至于获得正确方向的途径,我想你大概也已经发现了吧。先别急着说出来,像素处理单元变迁的故事还没讲完呢,我们不妨继续看看后面的双方对战情况吧。
● 卧薪尝胆,三千越甲可吞吴
AMD既然继承了ATI的一切,它就必须为从ATI继承来的狂妄付出代价。R600构架的失败几乎将AMD图形部门逼入绝境。当年的NV3X虽然在构架上一样出现了非常严重的战略性错误并导致了完全的失败,但通过优秀市场划分及运作策略的弥补,最终好歹勉强维持了说的过去的市占率。这种情况在R600身上并没有得到重演,在多种原因的累计之下,AMD显卡的市占率在R600发布前后一直都在下滑,甚至到了丧失存在感的地步。
绝境,真正的绝境,后退一步就是万劫不复的绝境……
绝境虽然凶险,但却也能逼出一个人最大的潜能。在R600失败带来的一片萧瑟中,AMD图形部门并没有放弃和轻言失败,他们坚韧的咬着牙继续前进,充分正视了自己的处境和地位,一步步的修正着自己先前所犯下的错误,不断的优化着R600构架的逻辑结构,寻找着适用于当前构架改进的突破口,期待着美好明天的最终到来。
有志者,事竟成,破釜沉舟,百二秦关终属楚!苦心人,天不负,卧薪尝胆,三千越甲可吞吴!这份坚韧和决心为AMD图形部门赢得了生存下去的机会,很快,翻身的机会来了。
其实不难发现,R600的构架强调的是吞吐能力,而劣势在于延迟的掩盖能力不足,所以要解决R600构架的运算效率问题,最终的核心就成了解决延迟掩盖能力,提升单元复用率。对于缓存体系和运算单元的改进不可能一蹴而就,稍有不慎就会出大乱子,既然一时之间难以提升缓存体系来掩盖延迟,ALU的逻辑结构也不太可能发生大变化,那剩下的方式就只有一个了——继续放大吞吐能力,以最暴力的手段来掩盖延迟带来的影响。
但是暴力放大吞吐能力这事情说的轻巧,做起来风险极大的,要放大吞吐能力,就要大幅提升运算单元的数量,而这么做也就意味着要大幅增加芯片的晶体管总数。如果晶体管数量大到超过了当前工艺所能够承受的范围,这种放大不仅不能成功,而且本身也会从正面意义摇身一变成为阻碍产品发展的负面因素。而贸然使用没有接触过得新工艺,对于任何一家公司来说都是极大地冒险。怎么办?
没办法了,赌一把吧!
也许是之前的努力和不放弃的信念感动了上苍,AMD在RV770上大胆赌博的两样东西——GDDR5显存和55nm工艺,全部获得了成功。借由先进的工艺,RV770成功的将像素处理和运算部分,也就是ALU的规模放大了惊人的250%,被大幅放大的单位吞吐能力很好的起到了掩盖执行延迟的作用。同时为了进一步弥补缓冲体系的不足,AMD还在RV770中引入了LDS单元作为重要的补充,虽然对LDS的使用在整个RV770时代并不顺利,但依旧大幅缓解了原来严重不足的缓冲体系问题。最后,新加入的高速GDDR5显存不仅为图形处理的其他部分提供了良好的助益,同时还因为其极高的带宽而“意外”的成了寄存器溢出之后可供选择的缓冲体系。有了这些改进,RV770的性能相对于R600/RV670有了大幅提升,虽然在绝对性能上依旧无法和发展自G80的GT200相提并论,但凭借小芯片策略,RV770依旧获得了市场的极大认同和褒扬。
RV770的出现,一举将绝境中的AMD图形部门从悬崖边拉了回来,为他提供了宝贵的喘息的机会,NVIDIA在同期推出的GT200虽然将G80的诸多优势和优点予以了充分的强化,并进一步添加了诸如原子操作等先进和优秀的设计,但因为众所周知的原因,
这些设计并没有带来客观的对应性能提升,同时为这些设计以及其他像DP之类与当前图形处理过程没有联系的设计所背负的芯片面积负担和发热,也让GT200饱受市场及消费者的诟病。因此虽然GT200更加符合微软对图形应用方面的新要求,但这一次战斗的胜利依旧是属于RV770的。
跟NV40一样,在精彩的像素处理单元设计大战中,RV770在R600失败之后扳回了一城。虽然它并不像NV40的胜利那样富有曲折的剧情和悬念色彩,但整个RV770所散发出来的那份坚持的可贵,以及诚恳的对过去的检讨,依旧令我们感动不已,仿佛让我们看到了技术重新回归正途的希望。每个人都在期待着AMD为我们奉上更加精彩的表演,并以自身的努力积极的推动业界以及技术的不断进步。
但令人失望的是,我们所期待的这一天,至今仍未到来……
● 卧薪卧到半身不遂,尝胆尝成饮鸩止渴……RV770为AMD取得了双赢,于技术层面上,它巧妙的使用大规模并行吞吐来掩盖延迟的做法得到了广泛的肯定,于市场层面,得益于小芯片策略的良好运作以及广大爱好者的期许,它也抢回了很多曾经失去的市占率。这本来是一片大好的形势。AMD完全可以利用这次机会检讨自己和NV在过去所犯下的相同的错误,积累经验,展开与微软的进一步合作,将自身的构架设计以及整个图形领域推向更好的未来。
但在获得了RV770的成功之后,AMD再次收获了一个错误的信号。跟以前一样,AMD再次误以为自己所选择的方向,以及对未来的预测是正确的。微软神马的都不重要,他说的根本不算,我甚至可以说微软在阻碍技术的进步和发展!吞吐才是王道,shader灵活性以及多用性的问题无关紧要,起码是可以慢慢悠悠的去弥补。只要我推出的东西市场就会买账,我说的市场就会去相信和接受,我想要的市占率即便现在不属于我,总有一天也会回到我身边。我为此所要付出的代价,只不过是去赌一下先进工艺,然后不停地放大规模就行了。只要能赌赢,I'm the King of the World!Again!
好吧,我承认类似的错误信号已经出现了好多次了,屏幕前的你又有了强烈的即视感也很正常。但历史就是这么的幽默,真的是应了那句名言了——the only thing we learn from history is that we learn nothing from history,翻译的粗俗些,我们从历史中学到的唯一的东西,就是我们从历史中毛都没有学到……
在RV770与GT200的对决落下帷幕之后,微软发布了全新一代图形API——DirectX 11,其中的Shader Modle5.0将人类对像素的处理,以及对像素处理单元的应用提升到了一个全新的高度。在先前的Shader Modle4.0更加灵活的shader应用的基础上,大商人引入了Compute Shader这一创造性的概念,通过打破几何关联的方式将像素处理单元的运算能力彻底的释放了出来。在Shader Modle5.0中,通用计算和像素乃至整个图形计算的界限已经变得极其模糊,过去看似对图形计算毫无帮助的通用计算设计,现在都得到了平反昭雪。再加上并行kernel等新技术的引入,Shader Modle5.0成了有史以来最强大的图形API,人们都热切的期待着AMD和NVIDIA能够奉献出完美支持新API的图形构架。
结果,最先等来的,是个半身不遂……
收获了错误信号的AMD果然没有辜负历史的铁律,摆在我们面前的RV870,已经完全达到了不知所云的状态——RV870的ALU团簇结构相对于RV770完全没有任何改进,依旧维持4D+1D VLIW的设计思路,线程粒度也未有任何变化,仅在寄存器方面完成了对Shader Modle5.0的基本支持,最大的改进就是ALU又多了一倍。uncore的缓存部分同core部分相当,GDS虽然提升到了64K,但这更多的是出于对Shader Modle5.0对于shared资源32K下限的机械迎合,相比于成倍放大的运算资源来说GDS依旧完全不够用,甚至AMD都完全没有搞清楚微软对32K shared下限的定义究竟在哪个层级。另一级缓冲,也就是LDS的读写方式虽然有了不小的改进,但也只是在做竞争对手在几年前就已经做好了的事情而已,整个陈旧的缓存体系对于Shader Modle5.0的全新要求根本没有任何的帮助。RV870不管从哪个角度来看,都只是一个运算和后端资源大幅放大,然后仅仅是“支持”或者说能够运行Shader Modle5.0代码的RV770胖子版。它的最大收获,仅限于没有任何变化的简单直接设计所带来的相对较低的功耗,已经极端贴近小芯片策略允许上限的核心面积尺寸,以及“世界上第一块支持DirectX 11”但却几乎不具备DirectX 11性能的显卡的名号。
Yes,the only thing we learn from history is that we learn nothing from history……
我们已经一遍又一遍地重复了类似的错误,再多重复一遍实在是很没有意思了。RV870这种对DirectX 11相当机械的,甚至是透着不情愿的迎合,让它付出了性能方面的沉重代价——只要应用环境进入真正的DirectX 11领域,哪怕是现在这种并不成熟的DirectX 11,甚至是那些根本算不上是DirectX 11应用、只不过罩了一层简单的“DirectX 11外壳”或者仅用了跟DirectX 11的灵魂关联不大的曲面细分的场合,RV870的性能就会马上变得毫无竞争力,它作为一款DirectX 11 GPU,存在的意义竟然是传统的DirectX 10甚至是更传统的DirectX 9环境下的应用。R600发展到RV770可以说是坚韧不拔的坚持,以及对既有构架的剩余价值在利用,到了RV870还没有任何变动,就成了抱着裹脚布不放了……
当然,RV870并不孤单,NVIDIA在刚进入DirectX 11时也没有多少优秀的表现,豪华的功耗,豪华的温度表现,受困于这两个豪华而产生的人类历史上第一款被阉割规模的旗舰,以及同样受困于这两个豪华所导致的与上代相同的1V1完胜、1V2完败、然后还没能力2V2的性能表现,这些都给初代Fermi带来了相当大的困扰。但我们不难发现,其实这些问题均来自EDA相关领域,从逻辑结构上来讲,Fermi构架的表现是无可指摘的。彻底的GPC并行设计,灵活的多级Unified cache体系,充沛的运算资源和科学高效的多级线程仲裁管理机制,这些紧贴微软图形API需求的设计不仅在工艺改进但结构完全没有变化的Fermi2.0中得到了充分的性能释放,也再一次让NVIDIA完全站到了AMD的对立面上。RV870的设计复杂度,甚至还不如Fermi一个GPC来的高,这让RV870几乎丧失了在构架层面与Fermi进行竞争的资格——他们根本就不是一个时代的设计,苛求RV870与Fermi进行DirectX 11相关的较量,无异于让关公去长沙外围面对侵略者的铁蹄一般……
AMD敏锐的意识到了危险,虽然市场依旧买账,但这个前面已经提到过的市场还能买账的原因你我心里都清楚,AMD心里同样清楚。R600构架发展到RV870为止已经触碰了诸多来自物理层面的底限,想要进一步透支规模几乎是不可能的事情了。如果再不在IC设计上提供对更加灵活的shader的支持,同时将重心从甚至是放在几年前都应该已经成为历史的单纯吞吐领域转移到计算与图形的结合方面,而是饮鸩止渴一般的继续胡乱放大规模,那么等待AMD的,将会是另一个比R600更加黑暗的绝境。而如果再被逼入这种绝境一次,没有人能够保证AMD有再次从其中全身而退的幸运。因此,我们看到了积极改进运算和逻辑结构的Cayman构架,看到了大幅变革并借鉴竞争对手已有的先进经验的GNC,这从侧面也说明了AMD实际上是清醒的——如果真如某些人认为的那样,R600一路发展到RV870的路线都是合适和正确的,AMD走了竞争对手没走的正确的道路,我们显然没有可能看到这些转身的动作。这些积极的举措不仅为AMD的未来带来了希望,同时也为这场持续了十余年且一直精彩纷呈的像素处理单元设计大战带来了继续下去的希望。
只要有希望,生活就是美好的。
● 弱小和无知不是生存的障碍,傲慢才是
我要真诚的对每一位读到这里的读者说一声——辛苦了。回顾像素处理单元的这场持续了十年之久的纷争,实在是一件非常辛苦的事情。能够在这个浮躁的读图时代静下心来阅读这并不算短的一段文字,这不仅是对笔者的肯定,更是对图形界这十年的肯定。
在这篇GPU大百科全书番外篇中,我们花费了巨大的精力梳理了可编程像素处理单元这十年来的几次交锋,以及胜负背后的故事,其目的并不是翻炒历史的冷饭,或者对已经尘封的往事加以鞭尸。我们这么做的目的,在于通过看似浮华的故事以及纷繁的技术细节差异,来展现技术进步和发展背后的哲理。也许,细心地你已经悟出了我们所要展现的哲理——
弱小和无知不是生存的障碍,傲慢才是。
在这段长达10年得战争中,没有一次战役的失败能归结为技术层面的落后或者弱小,也没有一场胜负是由知识或者技术储备的总量直接决定的。不论NVIDIA还是ATI/AMD,每一次惨败的背后都躲藏着同样的一个原因——傲慢和狂妄。因为傲慢和狂妄,本该沉淀的企业变得自我膨胀;因为傲慢和狂妄,原本清晰正确的未来决策变得模糊和错误;因为傲慢和狂妄,本该紧密的合作变得疏离;因为傲慢和狂妄,本该是陈旧的结构设计思路被当做了合适的处理手段;因为傲慢和狂妄,甚至应该快速进步的技术领域,其前进的步伐也因为维护各自利益和错误疮疤的争吵受到了很大的干扰……
傲慢和狂妄,正是一切的罪魁祸首。
尽管并不是每个人都喜欢大商人微软,但这位活雷锋同志目前确实主导和统治着桌面图形领域。也许他真的阻碍了技术的进步,但毋庸置疑的是现在的我们无力反抗。而且话说回来,每一代DirectX的进步,也确实都为我们带来良好的视觉体验。想要在可见未来内维持良好的发展,提供符合技术和市场需求的GPU产品,紧跟微软的步伐是必要的。这10年来每一场像素处理单元大战的胜负,都在生动的说明着这个事实,尽管它归根结底依旧是傲慢和狂妄的表象而已。
对于技术细节及特色的追求和喜爱,其实应该带给我们很多技术以外的东西。如果我们能从中抽离出深层次的真相甚至是哲学道理,而不是单纯的将之作为争吵的工具或者YY的资本,那么我们对技术细节的追求,也就变得更加有意义了。弱小和无知不是生存的障碍,傲慢才是。这个道理不仅适用于我们今天所涉及的讨论,对于生活又何尝不是如此呢?技术本身就是生活的一部分,能够从技术中领略到生活的奥妙和真谛,从而让生活变得更加美好,这不是一件很美好的事情么?
在下一期的GPU大百科全书中,我们将继续流水线对图形处理的进程。我们将要面对的是与像素处理同等重要的环节——纹理材质操作。在下一章中,我们除了揭示纹理和材质操作的诸多技术特色之外,还会向你展现TMU这个纯图形单元不为人知的另类一面。敬请期待吧。
最后,感谢刘慈欣先生,如果您能够看到这篇文章的话,谢谢您优秀的作品向我们揭示的一系列横亘古今的道理。本文的成文,不过是对这些道理的一次应用罢了。谢谢所有读完本文的读者,你们在阅读上的坚持已经实践了本文关于坚韧的描述。谢谢!