自NVIDIA的Turing架构问世已经过去了一个多月时间,GeForce RTX 20系列的发布以及实时光线跟踪技术的推出,让NVIDIA将使用多年的“GeForce GTX”更名为“GeForce RTX“,并彻底改变了游戏显卡。实时光线跟踪、RT Core、Tensor核心、AI功能(即DLSS)、光线跟踪API,所有这些都汇集在一起,为游戏开发和GeForce显卡的未来发展指明了新方向。
与过去推出的产品大不相同,NVIDIA已将其最新显卡的介绍内容分为两部分:架构和性能。近日,NVIDIA终于揭开了全新Turing架构细节的面纱,虽然一些有趣的方面尚未得到官方解释,还有一些环节需要与客观数据一起深入研究,但也让我们有机会深入了解那项为GeForce RTX冠名的技术:光线追踪。
虽然使用Turing的实时光线追踪功能需要借助DirectX的光线追踪(DXR)API、NVIDIA的OptiX引擎或未发布的Vulkan光线追踪扩展,而用于游戏的DXR还没有发布给终端用户,但鉴于NVIDIA传统上具有开发人员和中间件(例如GameWorks)的强大生态系统,他们希望利用高端游戏来激发消费者对混合渲染(光栅化+光线跟踪)的支持。
正如之前所说,NVIDIA正在通过混合渲染来努力推动消费级GPU实现脱胎换骨的转变。而使NVIDIA迈出这一步的背后原因,除开“实时光线追踪是计算机图形学的圣杯”这一点之外,还有很多超越了图形纯粹主义的其他潜在动机。
由于NVIDIA用于光线追踪的RT Core是Turing架构的两项技术基石之一,因此在我们深入了解Turing架构之前,最好先讨论清楚什么是光线追踪,以及为什么NVIDIA会在其上投入如此多的芯片资源。
简而言之,光线追踪是一种渲染方式,可模拟光在现实世界中的表现(反射、折射等)。实现它的最大问题在于它近乎于无底洞一样夸张的性能的需求,如果使用最原始的方法来尝试计算场景中每个光源发出的所有光线,将会在场景中追踪到无穷无尽的光线。
多年以来,算法工程师们为光线追踪开发了许多优化措施,其中最重要的是把“光照”这一简单的概念颠倒过来,不是从光源开始追踪光线,而是从屏幕、从观测者的视点逆向追踪光线,这样便可以只计算实际到达屏幕的光线,大幅缩减所需的计算量。
然而即便使用了包括此法在内的许多优化方式,光线追踪对性能的需求依然高的惊人。除了最基本、最粗糙的光线追踪之外,其他任何情况都依然超出了实时渲染的范围。这些优化技术仅仅是让光线追踪可以在计算机上以相对“合理”的时间完成,当然这个“合理”是以小时或天来衡量的,这要取决于场景的复杂程度以及你所期望达到的渲染效果。实际上到目前为止,光线追踪一直被主要是3D动画电影等“离线”场景。
光线追踪的高成本意味着它还不能用于实时图像渲染,因此计算机行业从一开始便使用了一种名为光栅化的渲染方法。
虽然名字沾一个“光”字,但整个光栅化渲染中其实根本没有“光线”的概念。光栅化(Rasterization)指的是3D几何转换为2D像素的过程,所有的画面特效都只是针对一个个像素的操作。
当游戏开始渲染一帧画面时,首先由CPU生成游戏场景中所有物体的顶点,然后把所有顶点的坐标信息发送给GPU内的几何单元。几何单元以屏幕位置为基准构建出可视空间,将这些顶点按照坐标安置到空间中,紧接着将顶点连接成线框,构造出物体的轮廓,然后在表面覆盖上一层带有带光照信息的底层纹理作为蒙皮。到这一步,我们的游戏画面便初具几何形态。
接下来便是整个光栅化渲染流程的核心:光栅化,GPU内的光栅化单元(Rasterizer)依照线透视关系,将整个可视空间从三维立体形态压成一张二维平面。之后流处理器再根据场景中物体之间的几何位置关系,通过各种渲染算法,确定哪些像素亮&有多亮,哪些像素暗&有多暗,哪些像素是高光,哪些像素是阴影。
在流处理器忙着计算像素信息的同时,GPU内的纹理单元也开始将预设的“整张”纹理材质剪裁成画面所需的形状。最后,流处理器和纹理单元分别把计算好的像素信息和剪裁好的纹理材质递交给处于GPU后端的ROPs,ROPs将二者混合填充为最终画面并输出。除此之外,游戏中雾化、景深、动态模糊和抗锯齿等后处理特效,也是由ROPs完成的。
看到这里应该明白,我们看到的每一帧游戏画面,都是GPU画给你的一张3D立体画而已。3D立体画看起来真不真实,取决于绘画者的水平如何;而光栅化渲染出来的画面真不真实,取决于渲染算法是否先进和完善。
光栅化的简单和快速决定了其对现实世界中画面的模拟是有限的,这也导致了光栅化普遍存在光照、反射和阴影不自然等缺陷。如果光栅化是如此不准确,游戏如何进一步提高其图像质量?
当然可以继续这么走下去,光栅化解决这些问题并非不可能,只是所需要的计算性能将会高速膨胀。就像撒一个谎要用十个谎来圆一样,某些情况下想用光栅化渲染生成逼真的画面,甚至比光线追踪的自然过程更复杂。
换句话说,与其在光栅化这种本质是视觉欺骗的渲染方式上消耗这么多性能,何不把这些努力投入另一种可以准确渲染虚拟世界的技术上?
2018年,整个计算机行业都在思考这一问题。而对于NVIDIA来说,前进的道路不再是纯粹的光栅化,而是混合渲染:将光栅化与光线追踪相结合,其想法是在有意义的地方使用光线跟踪——用于照明、阴影和其他所有涉及光的相互作用的内容,然后使用传统的光栅化来处理其他一切,这也正是Turing架构的核心思想所在。
这意味着开发人员可以两全其美,根据需求平衡光栅化的高性能和光线追踪的高质量,而无需立即从光栅化跳转到光线追踪并失去前者的所有性能优势。到目前为止,NVIDIA及其合作伙伴所展示的案例都是很容易实现的,比如精确的实时反射和更好的全局光照,但显而易见混合渲染可以扩展到任何与光照相关操作。
然而,NVIDIA、微软和其他公司也不得不为其从零开始建立一个生态系统,他们不仅要向开发人员推销光线追踪的优点,而且还要教开发人员如何以有效的方式实现它。
不过我们现在依旧可以可以先来讨论一下光线追踪,看看NVIDIA如何通过构建专用硬件单元,将实时光线追踪变为现实。
可以说,NVIDIA在Turing上下了很大的赌注,传统的GPU架构可以高速处理光栅化渲染,但并不擅长光线追踪这项任务。因此NVIDIA必须为光线追踪增设专用硬件单元,而这些额外的晶体管和电力消耗却对传统的光栅化渲染没有直接的助益。
这部分专用硬件单元很大程度上将被用于解决光线追踪的最基本问题:判定光线与物体的相交情况。这个问题最常见的解决方案是将三角形存储在一个非常适合光线追踪的数据结构中,这种数据结构称为BVH(边界体积层次结构)。
从概念上讲,BVH相对简单,它并不是检测每个多边形以判断是否与光线相交,而是检测场景的一部分以查看是否与光线相交。如果场景某部分与光线相交,则将其细分为较小的部分并再次检测,依次继续下去直至单个多边形,此时光线检测得到解决。
对于计算机科学家来说,这听起来很像二元搜索的应用,而且确实如此。每次检测都允许丢弃大量选项(在光线追踪中为多边形)作为可能的答案,便可以在很短的时间内到达正确的多边形。BVH反过来又存储在本质上是树数据结构的东西中,每次细分(边界框)都存储为其父边界框的子节点。
现在BVH的问题是,虽然它从根本上减少了所需判断的光线相交量,但这些针对的都是单独一条光线,当每个像素都需要多条光线经过时,每条光线都需要进行大量检测,它的计算量依然不低。这也是为什么使用专门的光线追踪单元进行硬件加速如此重要的原因。
我们来看看这次的Turing架构,新的Turing SM看起来与上一代的Pascal SM非常不同,但了解Volta架构的人肯定能注意到Turing SM与Volta SM是非常相似的。
与Volta一样,Turing SM被划分为4个子核(或处理块),每个子核具有单个warp调度器和调度单元,而Pascal的2个分区设置是每个子核的warp调度器具有两个相对的调度端口。
从广义上讲,这样的变化意味着Volta和Turing失去了在一个时钟周期内从线程发出第二条非依赖指令的能力。Turing可能与Volta在两个周期内执行指令相同,但调度程序可以在每个周期发出独立指令,因此Turing最终可以通过这种方式维护双向指令级并行(ILP),同时仍然具有两倍于Pascal的调度程序数量。
正如我们在Volta中看到的那样,这些变化与新的调度/执行模型紧密相连,而Turing也有独立的线程调度模型。与Pascal不同的是,Volta和Turing都有每个线程的调度资源,有一个程序计数器和每个线程的堆栈来跟踪线程的状态,以及一个收敛优化器来智能的将活动的同warp线程分组到SIMT单元中。
就CUDA和ALU(算术逻辑单元)而言,Turing子核具有16个INT32单元,16个FP32单元和2个Tensor单元,与Volta子核的设置相同。使用像Volta这样的拆分INT/FP数据路径模型,Turing还可以同时执行FP和INT指令,而这与RT Core密切相关。Turing与Volta的不同之处在于Turing没有FP64单元,其FP64的吞吐量只有FP32的1/32。
虽然这些细节可能更偏向于技术方面,但Volta的这种设计似乎是为了最大化Tensor Core的性能,而最大限度的减少了破坏性并行性或与其他计算工作负载的协调。对于Turing的第二代Tensor Core和RT Core来说情况也是如此,其中4个独立调度的子核和粒度线程处理对于在混合游戏导向工作负载下实现最高性能非常有用。
在内存方面,Turing的每个子核都有一个类似Volta的L0指令缓存,具有相同大小的64 KB寄存器文件。在Volta中,这对于减少Tensor Core的延迟很重要,而在Turing中这可能同样有利于RT Core。Turing SM每个子核也有4个加载/存储单元,低于Volta中的8个,但仍然保持4个纹理单元。
新的L1数据高速缓存和共享内存(SMEM)进一步向上扩展,它已被改进并统一为单个可分区内存块,这是Volta的另一项创新。对于Turing来说,这看起来是一个组合的96 KB L1/SMEM,传统图形工作负载分为64KB专用图形着色器RAM和32 KB纹理高速缓存和寄存器文件溢出区域。同时,计算工作负载可以将L1/SMEM划分最多64 KB作为L1,其余32 KB作为SMEM,反之亦然(Volta的SMEM最高可配置为96 KB)。
在Turing上,光线追踪并不能完全取代传统的光栅化渲染,而是作为“混合渲染”的一部分而存在,而且“实时”也只能在每个像素只通过少量光线并辅以大量降噪的情况下实现。
出于性能原因,现阶段开发人员将有意识和有针对性的利用光线追踪来实现光栅化无法实现的部分逼真效果,例如全局照明、环境光遮蔽、阴影、反射和折射等。光线追踪同样也可以限于场景中的特定对象,并且使用光栅化和z缓冲代替主光线投射,而仅对次光线进行光线跟踪。
凭借光线追踪在计算机图形领域的重要性,NVIDIA Research相当长一段时间内一直在研究各种BVH实现,以及探索光线跟踪加速的架构问题。不过NVIDIA并未透露有关RT Core或其BVH实现的许多细节。
RT Core与Tensor Core不同,Tensor Core更像是与FP和INT核心一起的FMA阵列,而RT Core更像是典型的卸载IP块。与子核中的纹理单元非常相似,RT Core的指令被路由到子核之外,在从SM接收到光线探测器后,RT核心继续自主遍历BVH并执行光线相交检测。
这种类型的“遍历和交叉”固定函数光线追踪加速器是一个众所周知的概念,多年来已经有很多实现,因为遍历和交叉检测是计算密集程度最高的两种任务。相比之下,在着色器中遍历BVH将需要每条光线投射数千个指令槽,所有这些都用于检测BVH中的边界框交叉点。
RT Core还处理一些内存操作的分组和调度,以最大化跨多个光线的内存吞吐量。与许多其他工作负载一样,内存带宽是光线追踪的一个常见瓶颈,也是NVIDIA Research多篇论文讨论的焦点。考虑到光线追踪会产生非常不规则和随机的内存访问,SIP块中可能还有一些内存和光线缓冲区。
尽管Tensor Cores是Volta的典型特征,但此番Turing上搭载的第二代Tensor Core却是青出于蓝。
第二代Tensor Core的主要变化是增加了用于推理的INT8和INT4精度模式,通过新的硬件数据路径启用,并执行点积累积为INT32积。INT8模式的运算速度是FP16的两倍,或每个时钟2048次整数运算;INT4模式的运算速度是FP16速率的四倍,或每个时钟4096次整数运算。
第二代Tensor Core仍然具有FP16模式,并且能够支持纯FP16模式而没有FP32累加器。虽然CUDA 10还没有出来,但增强的WMMA操作应该能够解释任何其他差异,例如操作数的额外可接受矩阵大小。
GeForce RTX和Turing所带来的不仅是RTX这一全新品牌命名,还有将Turing的所有功能归为一体的NVIDIA RTX平台,包括:
NVIDIA RTX平台:包含所有Turing功能的通用平台,包括高级着色器
NVIDIA RTX光线追踪技术:RTX平台下光线追踪技术的名称
GameWorks Raytracing:光线追踪降噪模块的GameWorks SDK
GeForce RTX:使用NVIDIA RTX实时光线追踪与游戏相关的品牌
GeForce RTX:显卡品牌
NGX在技术上隶属于RTX平台,其最具代表性的是DLSS(深度学习超级采样)技术。DLSS使用专为游戏而设的DNN(深度神经网络),使用超高质量的64倍超级采样图像或真实画面进行训练,进而通过Tensor Core来推断高质量的抗锯齿结果。标准模式下,DLSS以较低的输入样本推断出高倍抗锯齿的结果,在目标分辨率上可达到与TAA相似的效果。
由于涉及深度学习,NVIDIA正在将纯粹的计算/专业功能推向消费者领域。在Turing上,Tensor Core可以加速DLSS等特性,也可以加速某些基于AI的降噪器,以清理和校正实时光线追踪渲染的画面。
Turing架构和Geforce RTX的发布,标志着计算机图形学在消费级市场上开始从虚假的视觉欺骗向着真实的追光逐影发展。到目前为止,业界对它们的赞誉也一直是毫不吝惜。
虽然Turing架构增设了专用的光线追踪单元RT Core,并辅以Tensor Core来进行AI降噪,但在冷静客观的思考下,根据雷锋网的了解,在1080P分辨率下,光线追踪具备基本可用性的入门门槛是每帧画面包含1亿条光线,如果以60fps为标准,就需要GPU达到每秒至少能处理60亿条光线的计算能力。
回过头来看刚刚发布的Geforce RTX 2080Ti/2080/2070三款显卡,它们的光线追踪性能分别是每秒处理100亿/80亿/60亿条光线,并且NVIDIA似乎表示未来更低的Geforce RTX/GTX 2060等显卡将不再支持光线追踪。
不知这是不是巧合,Geforce RTX 2070的光线追踪性能刚刚好压在了上面所述具备基本可用性的入门门槛上,这样来看,更低端的显卡不支持光线追踪也是情有可原。
此外,也许是目前的光线追踪算法过于追求简化,对光影关系的还原仍有可能出现错误。例如在NVIDIA用战地V这款游戏演示RTX效果时,汽车对于火光的反射便出现了一处错误,红框处的车灯罩是背对着车后的火光的,从角度上来看完全不应该有火光的反射:
且根据最近流出的性能测试来看,即便是最高端的Geforce RTX 2080Ti在开启光线追踪后,也仅能在1080P下将帧数维持45fps左右,显然还要大幅低于理论性能。种种情况表明,现阶段的光线追踪依然徘徊在“有可用性”的门槛边缘,Turing和Geforce RTX显卡是否已经迈过了这一脚,真的还不好说……
(原文发表于Anandtech,雷锋网编译)