图灵架构
参考文档:图灵架构白皮书
图灵架构是20系的架构,算是影响深远的一代架构,奠定了很多基础性的概念。
先从最小的计算单元结构看起。SM(Streaming Multiprocessor)是基础的计算单元。所有计算任务最终都要由SM中的一个或几个组件协同完成计算。一个SM包括4个warp、1个共用的L1 Cache/Shared Memory、4个Texture Unit和1个RT Core。RT core是用于加速光追的的硬件结构,主要加速了建立BVH和射线检测,是一个相对独立的模块。L1 Cache/Shared Memory以及Texture Unit分别负责存储数据和材质采样加速,这两个模块都是为Warp服务的。Warp负责实现具体的数据计算。
要想理解Warp,你需要新理解SIMD,本文就默认你理解了。
每个Warp共用一个指令发射器发送指令,控制16个FP32(32位浮点)计算核心和16个INT32(32位int)计算核心。FP32核心之间运行的指令相同但数据不同,你可以理解位一次性有16个像素点同时在计算,INT32核心同理。FP32和INT32可并行运行指令。warp一个共用的Register File用于寄存器存储,4个LD/ST模块用于加载和存储Cache数据。这也是为什么ddx和ddy能够很方便的获得,因为是运行在同一个warp上的不同像素间共用了寄存器和cache。warp还包含SFU(Special Function Unit),用于加速一些特殊函数指令,比如sin、sqrt等。
每个warp还有两个Tensor Core。你只需要知道它们是用来加速深度学习计算的,在游戏领域主要是DLSS在使用Tensor Core。
接下来看看图灵架构的整体组织形式。
SM被TPC(Texture Processing Cluster)管理,每个TPC有2个SM和1个PolyMorph Engine。PolyMorph engine主要负责获取顶点以及曲面细分。一个Raster Engine驱动六个TPC,组成一个GPC(Graphics Processing Cluster)。L2Cache为全体GPC共用。
NVLink主要用于多台GPU互联,应用场景是高性能计算和深度学习,对游戏领域影响不大。
艾达架构
参考文档:艾达架构白皮书
艾达架构是40系显卡的架构,也就是市面上最新的架构。相比于图灵架构,艾达架构可以说是没有根本性的突破,而是对每个模块都进行了细微的升级。这一代的卖点也主要集中在光追性能提升和DLSS 3.0,传统光栅化架构几乎没有变化。
在光追方面,艾达架构对BVH查找加速和半透明物体与视线相交加速上做出了重大突破。然而笔者在光追方面实际经验有限,没有实际感触,不做过多描写了。有兴趣的朋友可以看原文,技术还是很有趣的。
其实看到SM架构就已经知道艾达架构相比图灵架构没啥突破了。唯一的亮点就是图灵的INT32核心在艾达架构中也可以用于FP32计算了,所以在一定程度上提高了传统光栅化的性能。
真没啥好说的,就是图灵的pro max版本。
对游戏着色器编码的启示
说了这么多,终于到有实际作用的了。
- 每次DrawCall的着色器实际上就是在SM中以Warp为单位运行的,也就是说除非最后一轮凑不满,不然顶点着色器和像素着色器,基本上都是16个顶点/像素同时处理的。
- 为什么要避免动态分支,其实就是warp是SIMD的,如果在一个warp中的不同thread动态分支有不同的结果,这个warp就必须将所有动态分支的结果都运行一边。但是,如果有动态分支但在同一个warp中,分支结果相同,仅是warp之间结果不同,那么其实影响不大。如果同一个sm的不同warp间动态分支结果不同,那么可能会在一定程度上影响L1Cache的局部性。不同SM间动态分支不同就基本无影响了。
- 为什么要优化寄存器?因为当指令被阻塞时,需要将当前上下文的寄存器存在L1Cache中,那么如果一个thread中寄存器使用太多,在切换线程时就会占用更多的cache,那么可并发的线程的就会更少,导致最终被实际的阻塞,影响性能。
- 为什么要减少采样?因为GPU是一个计算便宜访存贵的系统(说的好像cpu不是一样,哈哈),且SM中texture unit的数量又是远少于Thread的,所以采样会带来阻塞,如果如前文所说可切换的线程满了,那么访存就会带来真实的stall,影响性能。
- 为什么访问buffer要尽可能满足局部性?因为L1cache是sm内共用的,也就是4个warp共用一个L1Cache,想要命中cache就需要局部性好。
- 在40系之前的GPU中,INT指令和FP指令是可以真实并行的,所以可以适当多穿插int指令来提高并行度。