可编程解决的是什么问题呢?主要是灵活性问题。早期的显卡架构以固定功能硬件为核心,将图形学中的渲染流程分解为多个固定阶段,并为每个阶段设计专门的硬件模块。这种设计虽然高效,却也限制了开发者的灵活性,因为程序员只能利用显卡厂商提供的预设功能,按部就班地完成渲染任务,无法实现更或个性化的效果。
随着3D游戏快速发展,开发者对更复杂的光照、阴影、纹理映射等效果产生了需求,之前的完全硬件固化的渲染管线就显得不够灵活了。于是,可编程渲染的想法应运而生,就是让开发者直接参与显卡渲染流程的控制,设计个性化的图形效果。为了应对这种技术趋势,英伟达做出了一个意义重大的决定:让显卡从传统的固定管线升级为支持可编程着色器的架构。这个决定好比把传统自动咖啡机升级为一个开放式的咖啡机。传统的咖啡机只能做固定的预设饮品(如拿铁、美式),而开放式的咖啡机允许用户自定义制作咖啡的方式,比如选择咖啡豆量、控制研磨时间以及调整牛奶或水的比例。
可编程着色器也是类似的道理,游戏开发的程序员能更自由地利用显卡的强大计算能力实现自己想要的渲染效果。然而,引入可编程的着色器意味着必须牺牲利润以建设基础设施,而且,不一定有太多游戏开发者采用。但英伟达当时的技术专家戴维·柯克极力劝说黄仁勋必须支持可编程着色器:“要干这个,短期内会增加一些成本,但随后,人人都会渴望拥有它,人人都想追赶我们。”黄仁勋起初对此持怀疑态度。然而,当他开始权衡不引入着色器的潜在成本时,他逐渐被说服。
从2001年起,英伟达开始逐步引入支持可编程着色器的显卡芯片。这些显卡允许程序员对顶点着色器、片段着色器(Fragment Shader)和几何着色器(Geometry Shader)等编写程序,以控制渲染流程的每个阶段。我把他们发布的产品年表放在文稿里,感兴趣的朋友可以查看。
-2001年,NVIDIA GeForce 3X是第一款支持可编程顶点着色器的芯片。-2003年,NVIDIA发布GeForce FX,继续增加了可编程的像素着色器模块。此外,顶点着色器增加了分支控制能力,同时支持静态和动态流控制。-2004年,伴随着NVIDIA GeForce 6X的发布,顶点着色器和像素着色器都实现了完全的可编程性。-2006年,NVIDIA发布了GeForce 8系列,这是首个支持几何着色器(Geometry Shader)可编程模块的显卡。从1999至2006年的7年间,英伟达终于把多个可编程模块集齐,使得他们的显卡成为首个支持多种3D渲染语言的架构平台。这进一步极大地提高了显卡的灵活性,能设计出更加复杂和个性化的3D图形效果。
然而,这种可编程的灵活性不是没有代价的。且不说额外的成本,单让开发者使用都不是一件容易的事情。为了让更多人能用上可编程显卡,英伟达在2002年推出了专门的3D编程语言——Cg,全称“C for Graphics”。他们还开发了一本《Cg教程》,手把手教你怎么用Cg做出各种炫酷的图形效果。但是,尽管工具和教程都有了,学习成本还是太高。图形开发本身就涉及复杂的数学原理,再加上要学新语言,推广起来很困难。英伟达在这一时期的股价一度低迷。
黄仁勋当时支持把固定管线变成可编程的主要原因,是为了满足未来游戏开发者的个性化需求。但是他还有一个想法,就是“可编程”这种灵活性,可以让那些游戏设计师之外的人也有机会使用英伟达的显卡做些计算,从而为自己的产品找到新的应用场景。注意,这是一个后续影响很重大的想法。从2001年英伟达推出GeForce 3系列开始,一些科学家和工程师就开始琢磨:能不能用这些可编程显卡来解决我们领域的计算问题?这就是后来所说的GPU通用计算(General-Purpose computing on Graphics Processing Units),简称 GPGPU。
在2003年,两个研究团队发表了两篇重要论文,验证了可以用某些方法对显卡编程,解决矩阵相关的计算,并且速度可以比普通CPU要快得多。矩阵计算是诸多科学领域中的核心计算。很多复杂的数学模型、物理系统,或者处理大量数据的算法的底层原理,都可以用矩阵运算统一表述。举个例子,像流体流动、热传导或电磁场这样的复杂现象,会被转化成涉及许多变量和方程的数学模型,而这些模型通常用矩阵来表示,再通过计算矩阵来找到问题的解。
为什么显卡对于矩阵计算很适合呢?因为矩阵中的每个元素计算通常是独立的,可以同时并行处理。而显卡本来就是为了处理像素设计的,每个像素的处理也是独立的,所以天然适合这种大量并行的任务。但有个问题,当时的显卡完全是为图形渲染设计的,要用来做矩阵计算得“曲线救国”。你得把矩阵计算任务包装成渲染任务,最终,GPU输出的“渲染结果”实际上就是你想要知道的矩阵运算的结果。
这就像你想用洗碗机洗蔬菜。洗碗机本来是洗碗的,但你可以把蔬菜装在篮子里或小型筛网里再放进去,关掉洗涤剂,也能达到清洗的目的。然而,这种曲线救国的方式不仅效率不高,而且对开发者的要求极高。开发者不仅需要完全掌握能够对GPU进行编程的应用程序接口(API,例如OpenGL、DirectX或者英伟达的那个Cg语言),而且需要对GPU的底层极为熟悉。那么,如何降低编程的难度,让普通程序员更好地利用GPU来实现自己除了图像渲染以外的任务,就是一个很重要的问题。2000年左右,斯坦福大学计算机图形学专业的博士生伊恩·巴克(Ian Buck)也在思考如何将英伟达的显卡用到其他领域的计算中。
他拿到了美国国防部的资金支持,组了个团队,在2003年推出了“Brook”。Brook提供了更简单的编程接口,把复杂的GPU图形编程操作包装成便捷的并行计算工具。有了Brook,科学家们可以用更简单的代码来做并行计算,开始尝试用显卡做天气模拟、金融建模、医学成像等各种计算密集型任务。
这种新型客户的涌现,黄仁勋也注意到了。2004年巴克博士毕业后,黄仁勋立刻邀请巴克加入英伟达,开始了一个秘密项目,这就是统一着色器。
热门跟贴