游戏玩家对画面质量的追求是永无止境的。更高的分辨率、更细腻的纹理以及更流畅的帧率,成为衡量游戏体验的重要指标。这种需求对显卡的计算能力提出了越来越高的要求。在1996年发行的一款游戏《雷神之锤》(Quake)被视为当时显卡性能的试金石。这款游戏采用了多层渲染技术,比如在表现一面墙壁时,首先需要对光源影响墙面的明暗效果进行计算,然后再叠加墙壁的基础纹理和物理细节,例如血迹和裂纹。这种逐层叠加的渲染方法需要对像素进行多次计算,包括光照效果的计算、纹理数据的叠加以及额外细节的动态处理,才能最终绘制出逼真的画面。
更复杂的挑战来自游戏场景中的角色渲染。在一个充满动态的打斗场景中,不仅需要实时描绘每个角色的骨骼动画和细致纹理,还必须同时渲染出环境中的动态光影、火焰和爆炸特效。这些任务牵涉到数十万个三角形的实时计算,而且必须以流畅的帧率展现给玩家,对显卡的实时处理性能提出了极高要求。即使专门针对图像渲染任务,显卡的算力也显得越来越不够,如何增加显卡芯片的能力呢?
当时,3dfx公司是显卡市场的领军者,其解决方案是通过增加显卡上的图形芯片数量实现性能提升。他们的Voodoo显卡在同一张显卡上配备了两颗相互协作的芯片,通过芯片之间的分工合作,显著提升了图形渲染速度。我们可以看出,这个策略的核心思想就是并行。而3dfx的并行是在芯片层面上实现的。
但英伟达技术团队敏锐地意识到,3dfx的策略存在天花板。多芯片并行虽然在短期内能够胜任当时的计算需要,但其扩展性受限。一旦需要处理更复杂的游戏场景,多芯片架构的弱点必然暴露。例如在未来的游戏中,可能会有大量的光源实时计算,需要复杂的光照、纹理叠加和动态效果的渲染。在这种情况下,不断增加芯片数量的方法将显得捉襟见肘,因为芯片数量的增加不仅会带来高昂的成本和严重的散热问题,还会因为芯片间通信的延迟和带宽瓶颈而制约性能的提升。
英伟达提出了全新的解决方案,即在单一芯片内部实现并行化。这种设计的核心不在于芯片数量的增加,而是通过增加芯片内部的渲染管线来完成并行工作。一条渲染管线可以被视为一条流水线,它独立执行从顶点着色到像素处理的完整渲染任务。如果将芯片比作一个工厂,增加渲染管线就等于在工厂内新增多条生产线,从而显著提升渲染效率。
具体而言,对于要进行渲染任务的3D表面会分成多个独立的数据块,每个渲染管线处理不同的数据块。不同渲染管线之间独立工作,这样就能提高速度了。
拿之前奶茶店的例子来讲,这种并行方式,就相当于把当前的所有订单分给不同的店员,每个店员处理自己的订单,互不干涉。多个店员同时工作,整体效率就提高了。这种并行方式,属于“数据并行”。数据并行的本质是将数据分成不同的任务,分别由多个计算单元同时进行处理。
1998年,英伟达发布的Riva TNT显卡首次将这一理念付诸实践。与此前显卡上的单条渲染管线设计不同,Riva TNT配备了两条像素渲染管线,能够同时执行两倍的像素着色任务。Riva TNT的推出确立了英伟达在显卡技术领域的重要地位。英伟达以惊人的研发速度不断推动技术进步:平均每6个月便推出新款显卡,其性能通常达到其他制造商的两倍。
1999年初,仅创立不到6年的英伟达以6亿美元的估值成功上市。同年年底,黄仁勋推出一款跨时代的显卡,被外界称为“Voodoo 杀手”。这款显卡命名为“GeForce 256”,有四条像素渲染管线,每秒可以渲染1000万个三角形,并能够根据动态光源的位置,实时改变3D场景中每个像素的颜色。英伟达在推出这款显卡的时候,提出了“GPU”(Graphics Processing Unit,图形处理单元)这一全新概念,标志着显卡技术的一个重要转折点。
英伟达沿着增加渲染管线的道路狂奔:像素渲染管线的数目从2条,到4条,再到后来GeForce 6的16条,GeForce 7的24条。随着渲染管线数量持续增加,显卡的处理能力不断提升。
除了增加渲染管线之外,英伟达还通过另一种技术进一步提升显卡的性能。还记得我们说过的奶茶店的例子吗?我们之前说的数据并行方法,是把所有订单分成几组,每个店员单独负责一组订单。
除此之外,还有一种并行方式能提高系统的性能。这种方式叫做流水线并行。奶茶的制作过程,是可以分为很多前后依赖的步骤的。比如,假设制作一杯奶茶可以分为以下三个主要阶段:第一步,在杯中加入各种材料(如茶底、牛奶、糖水等);第二步,搅拌混合;最后一步,封口包装。
除了让多个店员独立负责不同的订单,我们可以有另外一种方式实现并行。假设有三个店员,每个店员负责上述的一个步骤。第一个店员完成向杯中加材料的环节后,他会将杯子传递给负责搅拌的店员;搅拌完成后,再传递给下一位负责封口打包的店员。
为什么这种方式可以提高效率呢?关键在于重叠。在订单源源不断的情况下,当第一个店员将第一杯奶茶的材料加入后,便可以立即着手制作第二杯,同时第二个店员开始搅拌第一杯奶茶。由此,每位店员始终全程忙碌,而不是在等待上浪费时间。
你现在可以打开文稿,看看下图。假设制作奶茶的三个阶段(加材料、搅拌、封口打包)每个都需要10秒钟,传统方法中完成一杯奶茶需要30秒,两杯则需要60秒。但如果采用流水线并行,制作两杯奶茶只用40秒。如果任务量增加到5杯,通过流水线操作可以将总时间压缩到70秒,比传统方法节约了一半多时间。
这种设计与工业流水线的原理相似。每个工人只需要专注于完成某个特定的工作,而加工对象在工人之间流动。这也是“流水线并行”这个名字的来源。
显卡的渲染任务和一杯奶茶的制作过程有着相似的逻辑。整个图形渲染分为多个连续的阶段,包括顶点着色、光栅化、像素着色等步骤。如果为每个阶段分配一个专门的组件负责,并让每个组件在完成任务后将结果快速传递给后续阶段,那么显卡的效率可以显著提高。这种流水线式的架构设计正是现代显卡性能飞跃的关键所在。
然而,为了实现流水线并行的最大效能,还需要注意两个重要因素:第一是任务的均衡性,第二是流水线的深度。
拿奶茶的例子来说。我们之前的计算中,刻意让三个阶段(加入材料、搅拌、封口打包)所需的时间是一样的,这就是均衡。如果某一阶段的任务比其他阶段更加耗时,就会成为“瓶颈”,导致后续阶段的等待,影响整体效率。
解决这一问题的方法通常是对任务量较大的阶段进行细分,或者为这一环节配备额外的资源。例如,将“搅拌”环节分为低速搅拌和高速搅拌两个步骤,分别交由不同人员完成,从而缩短任一阶段的任务时间,使流水线更为流畅。
这是任务均衡,第二就是流水线的深度。流水线越深,一个任务被切割成的阶段越多,每个阶段的粒度越细,整个流水线上工作的环节便越多,重叠度也越高。拿奶茶店举例。为了提高效率,我们把“加入材料”这个环节拆分,变成“加入茶底和牛奶”,以及后续的“加入辅料”这两个环节。将“搅拌”,拆分成先“低速搅拌”,再“高速搅拌”。将“封口打包”,拆分成“封口”和“打包”这两个环节。这样,原来的制作一杯奶茶就从三个环节变成了六个环节。假设我们为每个环节也配备一个店员,假设分解后的阶段完成时间缩减一半,总体制作一杯奶茶的时间维持不变。
当有了这个更深的流水线以后,第一杯奶茶制作还是30秒,但是第二杯奶茶由于可以在第一个环节之后就立刻启动,因此完成两杯奶茶的时间一共只需要35秒。而完成5杯奶茶的总时间是50秒,比之前的70秒进一步降低了。我们可以看出,流水线越深,那么重叠度就越高,效率越高。你可以打开文稿看一下图。
英伟达早期的显卡,例如1999年发布的GeForce 256,并没有实现真正意义上的流水线并行架构。其组件之间的任务交接依赖显存,顶点数据需要批量写入显存后,光栅化才能读取到完整的数据开始处理。打个比方,这就像奶茶店里负责“加入材料”的店员,他不是完成一杯奶茶就立即交给下一个店员,而是积攒了一批加好材料的奶茶后,才交给下一个店员处理。这种方式显然效率较低。
两年后,英伟达在2001年推出的GeForce 3是首次引入流水线并行架构的产品。与GeForce 256使用显存传递数据不同,GeForce 3增加了顶点缓存(Vertex Cache)。这个设计允许顶点数据在模块间逐步传递,而不需要等待整个批次的数据处理完成。这种架构让显卡的设计更贴近高效工业流水线的模式,各部分始终以更高的利用率运行,满足了不断增长的游戏渲染需求。
热门跟贴