RTR4:图形处理单元与渲染管道实现 v0.01
第三章
- GPU为一小部分高并行化的任务提供了加速,如z缓冲区,访问纹理图像和其他缓冲区,查找三角形覆盖的像素提供了定制芯片 ch23
- 本章介绍GPU 如何为其可编程着色器实现并行性
- 着色器是如何工作的:ch3.3
- 着色器的核心是小型处理器,执行相对独立的任务,如transform,fragment计算
- 数量级:每帧都有数千或数百万个三角形发送到屏幕,每秒可能有数十亿次着色器调用
- 存在的问题: 等待数据会降低性能
- 延迟:访问数据需要一些时间。判断延迟的一个基本方法是,信息离处理器越远,等待的时间就越长 ch23.3
- 存储在内存芯片中的信息将需要比本地寄存器中更长的时间来访问,内存访问:ch18.4.1
3.1 数据并行架构
-
CPU的特点与如何处理停顿
- CPU:多个处理器,每个处理器串行,(SIMD矢量运算除外
- 大量使用本地缓存,CPU 还通过使用诸如分支预测、指令重新排序、寄存器重命名和缓存预取等巧妙技术来避免停顿
-
GPU的特点
- GPU:含有大量处理器,称着色器内核(通常数千个
- GPU是流处理器,即数据与操作统一,各自相对独立,潜在的代价是可能存在等待情况
- GPU针对吞吐量(处理数据的最大速率)进行优化,相对高速缓存和控制逻辑在芯片的占比少,故单个内核的延迟要比CPU高,详细见参考
-
引入:一个运行实例
假设一个网格被光栅化,两千个像素有片段需要处理;一个像素着色
器程序将被调用两千次。想象一下,只有一个着色器处理器,世界上最弱
的 GPU。它开始为两千个片段中的第一个片段执行着色器程序。着色器处
理器对寄存器中的值执行一些算术运算。寄存器是本地的并且可以快速访问,因此不会发生停顿。着色器处理器随后会执行诸如纹理访问之类的
指令;例如,对于给定的表面位置,程序需要知道应用于网格的图像的像
素颜色。纹理是完全独立的资源,不是像素程序本地内存的一部分,并且
可能会涉及纹理访问。内存获取可能需要数百到数千个时钟周期,在此期
间 GPU 处理器什么都不做。此时着色器处理器将停止,等待返回纹理的
颜色值。
为了让这个糟糕的 GPU 变得更好,给每个片段一个小的存储空间来存
放它的本地寄存器。现在,着色器处理器不再暂停纹理提取,而是允许切
换并执行另一个片段,即两千个片段中的第二个。这个切换非常快,除了
注意第一个片段上执行的是哪条指令外,第一个或第二个片段中的任何内
容都不会受到影响。现在执行第二个片段。与第一个相同,执行一些算术
函数,然后再次遇到纹理提取。着色器核心现在切换到另一个片段,第三
个。最终,所有两千个片段都以这种方式处理。此时,着色器处理器返回
到第一个片段。此时纹理颜色已被提取并可供使用,因此着色器程序可以
继续执行。 处理器以相同的方式继续执行,直到遇到另一条已知会停止
执行的指令,或者程序完成。与着色器处理器一直专注于它相比,单个片
段的执行时间会更长,但作为一个整体的片段的总体执行时间会大大减少 -
SIMD:单指令多数据
- 上述实例通过切换到另一个片段让GPU保持忙碌来隐藏延迟,进一步的,分离指令执行逻辑与数据,即SIMD
- 优势:比单独逻辑+调度单元比,需要的芯片和功率更少
-
运行实例的GPU实现
- 线程:片段的每个着色器调用被称为1个线程(包含有所有需要的内存寄存器数据与空间
- warps或wavefronts:使用相同着色器程序的线程被打包成组,每组被8-64个着色器内核通过SIMD方式处理使用
- 每个线程被映射到一个SIMD lane(SIMD通道)
- 执行过程:
- 根据程序线程数量和warp包含的线程数量划分warp
- 执行一波warp,其中的线程同步执行,遇到内存提取则停止(stall)
- (swap)换上新一波warp,继续计算
-
warp替换时为何代价较小
- 数据和状态绑在线程上,swap只是使处理器切换下对象
-
性能指标:
- warp-swap技术的关键指标是占用率,即gpu上的线程越多,warp越多,则占用率高,这最终取决于线程携带的数据大小与gpu上寄存器的大小的关系
- 低占用率会导致性能不佳,内存获取的频率也会影响需要隐藏多少延迟,详细见参考
-
其他性能问题
- 分支,由“if”语句和循环引起的问题:
- 假设在着色器程序中遇到“if”语句。如果所有线程都评估并采用相同的
分支,则warp可以继续,而不用担心另一个分支。 - 然而,如果一些线程,甚至一个线程,采用备用路径,那么warp必须执行两个分支,丢弃每个特定线程不需要的结果 [530, 945]。这个问题称为线程发散
- 其中一些线程可能需要执行循环迭代或执行 warp 中的其他线程不需要的“if”路径,
在此期间让它们处于空闲状态
- 假设在着色器程序中遇到“if”语句。如果所有线程都评估并采用相同的
- 分支,由“if”语句和循环引起的问题:
3.2 GPU流水线简介
- 流水线的可编程性:
- 屏幕映射和合并可设置
- 剪裁与光栅化固定
- 其余可编程
- 逻辑管道的实现取决于硬件提供商:ch18 ch23
- 逻辑模型可以帮助您推断影响性能的因素,但不应将其误认为 GPU 实际实现管道的方式。
3.3 可编程着色器阶段
- 各类着色器共享一个通用编程模型,具有相同的指令集架构 ISA
- 该模型由通用着色器核心处理器实现,来处理负载均衡等具体任务
- DirectX的着色器语言(略)
- 基本数据类型是32单精度浮点标量和向量,整数最常用于表示计数器、索引
或位掩码。还支持聚合数据类型,例如结构、数组和矩阵。 - 每个可编程着色器阶段都有两种类型的输入:统一输入,其值在整个绘制调用中保持不变(但可以在绘制调用之间更改),以及变化的输入,来自三角形顶点或光栅化的数据
- 底层虚拟机为不同类型的输入和输出提供特殊的寄存器。各自数量取决于具体功能
- 变量输入寄存器
- 输出寄存器
- 常量寄存器(多)
- 临时寄存器(多)
- 纹理 (其次)
- 术语流控制是指使用分支指令来改变代码执行的流程。
- 静态控制流
- 动态控制流(性能问题
3.4 可编程着色和API演变
(略)
3.5 顶点着色器
- 输入组装器 input assembler
- 数据表示 ch16.4.5
- 实例化 ch18.4.2
- 三角形网格:
- 顶点
- 可选属性:颜色,纹理,曲面法线
- 使用三角形网格来 表示一个基础曲面(underlying curved surface),而顶点法线则用来表示这个曲面的方向,而不是三角形网格本身的方向
- 计算顶点法线的方法: ch16.3.4
- 功能
- 修改创建忽略每个顶点相关的值,颜色,法线,纹理坐标,位置
- 模型空间→同质裁剪空间 homogeneous clip space ch4.7
- 最少:必须输出位置
输入组装通常呈现为在执行顶点着色器之前发生的过程。这是物理模
型通常与逻辑模型不同的示例。从物理上讲,创建顶点的数据获取可能发
生在顶点着色器中,驱动程序会悄悄地为每个着色器添加适当的指令,程
序员看不到。
- 用途:
- 动画关节的顶点混合
- 轮廓渲染
- 对象生成:by creating a mesh only once and having it be deformed(变形)
- 使用蒙皮和变形技术为角色的身体和面部设置动画
- 程序变形,例如旗帜、布料或水的移动 [802、943]
- 粒子创建,通过沿管道发送退化(无区域)网格并根据需要为这些网格指定区域。
- 镜头失真、热雾、水波纹、页面卷曲和其他效果,通过使用整个帧缓冲区的内容作为屏幕对齐网格上的纹理进行程序变形。
- 通过使用顶点纹理提取应用地形高度场 [40, 1227]
3.6 镶嵌阶段
- 作用:根据需要对模型进行细分
- 组成:(DirectX和Openg)
- 外壳着色器(曲面细分控制器)
- 曲面细分着色器(固定)
- 域着色器(曲面细分评估器)
- 目的:(TODO)
- 参考:ch17 ch17.8 ch22.8
3.7 几何着色器
- 参考:ch10.4.3
- (TODO)
3.7.1 流输出
- 参考: ch13.8 ch4.4
- 在 OpenGL 中,流输出阶段称为变换反馈
- (TODO)
3.8 像素着色器
- 光栅化器还可以粗略地计算三角形覆盖了每个像素的单元区域的程度( ch5.4.2 )
- 延迟着色 ch20.1
- 处理相邻像素 ch12.1
- 像素着色器提供了任何内插值沿 x 和 y 屏幕轴每个像素的
变化量。这些值对于各种计算和纹理寻址很有用。这些梯度对于诸如纹理
过滤(ch6.2.2)之类的操作特别重要 - (TODO)
3.9合并阶段
- 透明度ch5.5
- early-z 测试 ch23 ch18.4.5
- (TODO)
3.10 计算着色器
- (TODO)
参考
- CPU的架构与相关技术:715
- GPU芯片相关:462
- warp切换的其他优化技术 945
- 占用率如何受寄存器数量和着色器使用的共享内存的影响 993
- 理想的占用率如何根据着色器执行的操作类型而变化 1911 1914
- 由“if”语句和循环引起的性能问题:530 945
- DirextX的输入组装器175 530 1208
- 程序变形,例如旗帜、布料或水的移动 802 943
- 通过使用顶点纹理提取应用地形高度场 40 1227
- 镶嵌着色器的作用 1493 225
进一步
- GPU与图形渲染管线 530
- GPU并行性与计算 462
- GPU的演变和设计 903
- 着色器编程: 1606 885
- 着色器算法:1512
- realtimerendering 对应参考
习题
- 请描述OpenGL中由顶点数据输入到绘制出一幅图像的具体过程