● 从像素向计算的跨越
如果要评价这世界上最悲情的职业,我觉得程序员一定会以高票数当选的。程序员永远都得不到他们想要的理想环境,当他们遇到某些问题并最终等到了这些问题的解决时,往往会发现这些问题的解决其实只不过是引出了新的问题而已,像素的世界就是如此。Shader Modle3.0确实解决了先前版本对于指令长度的限制以及执行效率方面的缺陷问题,但急剧放大的指令长度以及其本身的出发点却将另一个问题非常明显的凸现了出来,那就是执行单元的总体效率问题。
彩虹六号:维加斯的执行效率已经受到了Shader Modle3.0的制约
传统的Shader Modle中,Vertex Shader和Pixel Shader是完全分立的两组programs,他们拥有不同的寄存器要求,不同的指令格式以及不同的运算器要求。因此传统硬件只有使用专门的比例一定的Vertex Shader和Pixel Shader单元,将它们分开进行处理。这种举措本身从最开始就注定了很多不可调和的矛盾——固定单元比例的硬件凭什么就能达到程序员对Vertex Shader和Pixel Shader数量及分布的要求?Shader Modle3.0号称是破除一切限制的史上最自由的Shader Modle,结果到头来还是要程序员严格按照硬件构架的大致比例和节奏来分配自己的Vertex Shader programs和Pixel Shader programs,只要稍有出格,硬件马上会以直线下降的执行效率来回报你。
除此之外,这种固定比例还导致了非常严重的单元利用率低落的问题。假定一段shader programs中仅包含10%的Vertex Shader指令,剩下的90%都是Pixel Shader指令,那么当重载的Pixel shader单元全力动作的时候Vertex shader单元实际上是处在欠载状态的。这种情况反之亦然。一段实际的shader program是不可能完全做到50:50的指令平衡设计的,再加上指令的串行吞吐特性,程序员无论如何都不可能做到指令密度的平均化。因此我们不难发现,实际应用中根据传统的API设计出来的硬件经常会出现大面积的负载不平衡的现象。
正当程序员为自己一次又一次的看到自由的曙光,却又一次又一次的被打回到各种束缚中而黯然落泪时,一只手轻轻地递过来一张纸巾,程序员用纸巾擦拭着眼泪,却发现纸巾下面盖着一个金光灿灿的新API——DirectX 10。程序员惊讶的半张着嘴巴,正准备说些什么的时候,微软微笑着用它特有的浑厚嗓音说:“不用问了,我叫雷锋!”
使用Shader Modle4.0全新GI效果的《狂野西部》
DirectX 10以及其所带来的Shader Modle4.0可以说为图形界翻开了全新的篇章,它创造性的引入了Unified Shader的概念,将传统的Vertex Shader和Pixel Shader从软件和硬件层面上予以统一,shader programs内部不再需要严格按照格式来区分Vertex/Geometry/Pixel。软件变了,硬件也要跟着改,所以对于支持Shader Modle4.0的硬件来说,其执行shader programs的单元也从过去的分立式固定功能变成了更加强大完整且完全统一的通用ALU。因为ALU可以对全部shader进行无差别吞吐,整个硬件的执行效率第一次在理论上达到了100%。
Shader Modle3.0与Shader Modle4.0效果对比
Shader Modle4.0对像素来说有着极其重要的意义,它不仅通过统一ALU吞吐提升了硬件的执行效率,更让程序员们可以更加随心所欲的使用效率更高的指令。传统的DirectX 9硬件中的shader格式是非常固定的,Vertex Shader指令天生就是4D(X,Y,Z,A),而Pixel Shader指令因为硬件单元设计通常都是对应RGBA的3D+1D 结构的缘故,一般情况下也会写成4D。这导致了DirectX 9环境下的Pixel Shader指令无论属于何种应用,哪怕仅包含一条Z-buffer或者一条texture load,也要在指令结构上找齐成4D格式。这种格式的刻板要求极大的限制了程序员对shader尤其是Pixel Shader的发挥。在Shader Modle4.0环境下,统一且无限制的指令格式要求以及直接面向底层ALU的特点让程序员可以大胆的直接使用更加灵活的1D、2D指令以及各种算数函数,而不用担心任何来自硬件方面的限制,这让Shader Modle4.0的效率和灵活度提升到了一个新的高度。
与此同时,由于对最底层运算单元的直接开放,人们忽然发现原来GPU里竟然蕴藏着如此丰富的运算资源。常规GPU用来处理shader的大规模并行ALU,本身可以轻松的拥有数倍甚至数十倍于CPU的吞吐能力,通过Shader Modle4.0面向ALU的开放,现在程序员们可以通过编程手段将这些原本用于处理像素效果的运算单元拿出来进行数学计算。像素处理,终于开始了自己从图形向计算的跨越。