How GPUs Work



    在90年代之前,那种无所不在的交互式3D图形只能充斥于科幻小说中。而在90年代末,几乎每一台新计算机都包含了一个图形处理单元(GPU)——专用于提供高性能的、富有视觉性的、交互式的3D体验。
    这种戏剧性的转变其实是消费者对视频游戏的要求、制造工艺的进步和前向图形流水线固有的并行开发所导致的必然结果。如今,一个GPU的计算能力远胜于大部分强劲的CPU,而且差距在逐步拉开。
    此外,GPU已由传统的固定图形流水线慢慢转向灵活的通用计算引擎。现在,GPU可以直接使用图形硬件来实现很多并行算法。所有受基础计算效率影响的算法便能因此得到巨大的加速。事实上,GPU是首个广泛部署于桌面并行计算机上的东西。

图形流水线
    
    任何3D图形系统的任务都是将一个场景描述(比如像游戏这种每秒60帧的实时图形)合成一幅图像。这个场景包含了用于观察的几何基元、用于照明场景的光照——表明每一个对象的反射光,和观察点的位置与方向。
    GPU设计者习惯上将这种合成图像处理方式表示成一种具有专门阶段的硬件流水线。这里,我们对经典(传统)图形流水线进行一个高度概括。我们的重点是突出实时渲染计算方面。在这个领域,图形应用程序开发人员可以利用现代GPU作为通用并行计算引擎。

流水线输入
    
    大部分实时图形系统假设所有事物均由三角形构成,他们会将任何更复杂的图形比如四边形或者曲面,先分解成三角形。开发人员使用一个计算机图形库(如OpenGL、Direct3D)以一次一顶点的方式为图形流水线提供每一个三角形;GPU会将三角形所需的顶点集合装配。

模型变换
    
    一个GPU可以为场景中每一个逻辑对象指定它的局部坐标系系统,这很方便为对象进行自然地、分层次地定义。这种方便的价值在于:渲染之前,GPU必须首先将所有对象变换至一个共同坐标系统。为了保证三角形不会被弯曲或扭曲成曲面形状,这个变换被限制为简单的仿射操作,如旋转、平移、缩放等等。
    就像附录中“齐次坐标系”的解释,通过将每一个顶点表示在齐次坐标系中,图形系统可以只用执行一个矩阵向量乘法便可以表示全部变换模式。每秒百万级顶点所需的浮点矢量计算对硬件效率的需求正在驱动GPU并行计算革命。
    流水线阶段的输出是一条三角形流,这些都表示在一个共同的3D坐标系统中,这个坐标系统的观察点位于原点,观察方向与Z轴对齐。

光照
   
    一旦一个三角形处于全局坐标系统,GPU就可以基于场景光照来计算它的颜色。例如,我们来描述一个基于单点光源(想象一个非常小的灯泡)的计算。GPU合并所有有效单个光线来处理多重光线。传统图形流水线支持Phong光照模型,一种表面看起来近似塑料的模型。生成的材质结合了无光的基础漫反射和有光泽的高光镜面反射。Phong光照方程计算结果为输出的颜色,C = Kd × Li × (N.L)+ Ks × Li × (R.V)^S。
    Table 1定义了方程中每一个术语。这里的数学计算并没有计算的结构重要。为了评估这个方程的效率,GPU必须直接在向量上进行重复操作。因此,我们要不断地计算两个向量的点积,进行四元乘和加的操作。



摄像机模拟

    图形流水线接下来要在虚拟摄像机胶片平面表达每一个有色的3D三角形。就像模型变换一样,GPU也使用矩阵向量相乘,再次受益于硬件上的矢量操作的高效率。该阶段的输出是屏幕坐标系上的三角形流,时刻准备转变成像素。

光栅化

    每一个屏幕空间可见的三角形在显示时会有像素重叠;决定这些像素的就是光栅化。这些年来,GPU设计者已经将很多光栅化算法合并,从而得到一个很重要的观点:每一个像素可以有别于其他像素而独立对待。因此,机器可以并行处理所有像素——的确,一些独特的机器早已为每一个像素提供一个处理器。这种内在的独立性引导GPU设计者去建造越来越多的并行集合流水线。

纹理

    每一个像素的实际颜色可以直接来自光照计算,但为了更逼真,图像,也叫纹理经常覆盖在几何体上来体现错觉般的细节。GPU将这些纹理存储在高速内存中,每一次像素计算均会访问该内存来修改并决定最终像素的颜色。
    在实际中,GPU可能需要多种大小的的纹理图,这样比原生分辨率小了或者大了的纹理出现在屏幕上可以更逼真。纹理内存中图案的访问是很有规律的(相近像素趋于访问相近的纹理图位置),有专门的高速缓存帮助隐藏内存访问的潜伏期。

隐藏面

    在大多数场景中,一些对象会遮挡其他对象。如果每个像素被简单地写入显示内存中,则最后提交的三角形会出现在最前面。因此,在每个视图正确消除隐藏面需要将所有三角形从后到前的排序,这个操作昂贵到完全不可能用于所有场景。
    所有现代GPU均提供一个深度缓存,用于存储每个像素到观察点距离的一个内存区域。在写入屏幕之前,GPU先比较已有像素距离和新的像素距离的大小,然后只会在新的像素距离更近时更新屏幕内存。

图形流水线的进化

    GPU已由固定图形流水线进化到支持底层可编程计算。用于变换顶点和填充像素的固定功能单元已经归为一个统一的网格单元,或者叫着色器单元(Shaders)。Shader可以完成这些任务甚至更多。这种用越来越多的可编程单元来逐步取代单个流水线阶段的进化已经演变了好几代了。例如,发布于2001年二月的NVIDIA GeForce 3,引入了可编程顶点着色器。这些着色器提供可编程单元用于执行矩阵向量相乘,求幂和求平方根等计算。而且一段简短的默认程序也可使用这些单元来执行顶点变换和光照计算。
    GeForce 3还引入了像素处理的可重构性限制,揭示了硬件功能可作为一系列组合寄存器,用来实现新奇的视觉效果,如肥皂膜的彩色折射效果(Figure 1)。随后的GPU引入了更强的灵活性,添加对更长程序的支持,更多的寄存器和流控操作如分支、循环和子程序。
    ATI Radeon 9700(2002.7)和NVIDIA GeForce FX(2003.1)又将经常不适用的组合寄存器替换为纯粹的可编程像素着色器。NVIDIA其后的芯片,GeForce 8800(2006.11),又为基元输入阶段添加了可编程能力,允许开发人员自由控制如何用已变换的顶点构造三角形。如Figure 2,现代GPU实现了极好的拟真视觉表现。
    随着可编程性的增加,数值精度也随之提高。传统图形流水线只为每个颜色通道提供8位整数精度,所允许的值为0—255。ATI Radeon 9700将可用颜色范围提高到了24位浮点精度,随后的NVIDIA GeForce FX可同时支持16位和32位浮点精度。两家供应商都已宣布计划在接下来的芯片中支持64位双精度浮点。
    为了赶上图形性能不断的要求,GPU已经强势进入并行化设计领域。GPU一直使用四维向量寄存器就像Intel的CPU一直使用SSE指令。而在并行化时代,执行的四维处理器数目更是有了显著增长。从GeForce FX的4个到 GeForce 6800(2004.4)的16个,再到GeForce 7800(2005.5)的24个。而GeForce 8800拥有128个标量着色处理器,它们也可以运行在专用着色时钟上,是以前芯片时钟频率的2.5倍。因此,其计算性能相当于128×2.5/4=80个四维像素着色器。





统一着色器

    从固定流水线到灵活计算模型的最新进化脚步是统一着色器的引入。统一着色器最先在ATI为Xbox 360游戏机提供的Xenos芯片上实现,随后NVIDIA 的GeForce 8800芯片将其带到了PC机上。
    不同于为顶点着色器,几何着色器,像素着色器分别定制处理器,一个统一着色器架构提供一个很大的通用并行数据浮点处理器网格,足够承载运行所有这些着色器的工作量。如Figure 3所示,顶点,三角形和像素循环通过网格,而不是依次流过固定宽度的各个流水线阶段。
   由于不同的应用程序对各种着色器的要求有很大变动,甚至一个程序仅一种框架,所以这种配置(统一着色器架构)能得到更好的整体利用率。例如,一个视频游戏可能使用大量三角形形成一幅图像来绘制天空和遥远的地势。这在传统流水线中,像素着色器会迅速饱和,而大量顶点着色器处于空闲。一毫秒之后,游戏可能使用高度精细的几何体来绘制复杂的人物和物体。这种行为会立刻让顶点着色器陷入负荷,而大部分像素着色器处于空闲。
    对游戏设计人员而言,要将每幅图像上戏剧性振动的资源要求达到负载平衡是非常可怕的事,而且随着玩家视点和动作的改变还会出现不可预知的需求变化。另一方面,统一着色器架构却能从它的处理器池中给每种着色器类型按变化的百分比进行分配处理器。
    在这个例子中,绘制天空时,一个GeForce 8800可能会将它128个处理器的90%作为像素着色器,10%作为顶点着色器,而在绘制人物的几何体时,则将比例反过来。直接结果就是灵活的并行架构可以提高GPU的利用率而且为游戏设计者提供更好的灵活性。



GPGPU(基于图形硬件的通用计算)

    实时计算机图形学的高度并行化工作量极度要求很高的算法吞吐量和流存储带宽,但可以容忍单个计算的延迟,因为最终的图像仅仅显示16毫秒。这些工作特点发展成GPU架构的基础:由于CPU为低延迟而优化,GPU则为高吞吐量而优化。
    GPU的原始计算功率是巨大的:单个GeForce 8800芯片在简单的基准数值测试上能达到持续性每秒3300亿次浮点操作。功率不断增加的,可编程的,高精度的GPU正积极参与大型通用计算领域的处理研究。GPGPU研究人员和开发者使用GPU作为一个计算协处理器而不是一个综合图像的设备。
    GPU的特有架构不适合每一个算法。很多应用程序基于串行而且以不连贯的随机的内存访问为特点。尽管如此,很多重要的问题依然需要大量的计算资源,刚好映射到GPU的众核计算强度;或者它们需要通过大量的数据流,这刚好映射到GPU的流存储系统。
    向GPU移植一个选择算法比起为CPU专门优化的代码常常会有5到20倍的加速。有报道称,一些映射特别好的算法甚至有超过100倍的加速。
    著名的GPGPU成功故事包括斯坦福大学的Folding项目,这个项目使用全世界用户捐赠的多余器官研究蛋白质折叠加工。项目中一台新的GPU加速客户机在2006年10月发布后的一个月里进行了28000Gfops的计算量。这比自2000年10月以来运行在Windows上的CPU客户机的总运算量还要高出18%。
    另一个GPGPU的成功例子是,北卡罗琳娜大学与微软使用基于GPU的代码赢得了2006年TeraSort比赛IndyPennySort项目的冠军,该项目是用数据库操作标准排序来测试性能。在GPU商业领域,HavokFX使用GPGPU技术让物理计算提高了十倍,用于为计算机游戏中的物体添加更真实的行为动作。


    现代GPU可被看作第一代数据并行处理器产品。它们巨大的计算能力和快速增长曲线远远超过传统CPU,在数据并行计算专业领域有着显著的优势。
    我们期待未来GPU架构可以无限制增强可编程性与一般性,毕竟供应商和用户都不愿意牺牲让GPU一炮而红的专用架构。如今,GPU开发人员在大规模多线程并行计算上需要新的高层次编程模型,这个问题接下来也会影响多核CPU供应商。
    在未来,GPU供应商,图形开发者和GPGPU研究人员能否基于他们在商用并行计算的成功来超越计算机图形学起源,并为桌面并行计算环境开发出计算风格、技术和框架。

附录



PS:有些术语我也懵了。。。
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页