GPU和CPU的差异
CPU与GPU的设计对比
-
核心数量与计算单元:
- CPU:通常核心数量较少(如4到16个核心),每个核心都有独立的控制单元。这种设计使得CPU能够高效处理复杂的任务和多线程操作,适合需要快速响应和低延迟的应用。
- GPU:计算单元数量非常多(可能达到几千个),多个计算单元共享一个控制单元。这种设计使得GPU能够同时处理大量的并行任务,特别适合大规模数据处理和图形渲染。
-
内存设计:
- CPU:内存设计上强调大缓存和低延迟,以确保快速访问数据和指令。这种设计有助于提高单线程性能和响应速度。
- GPU:内存设计追求高带宽,能够处理大量数据的快速传输。虽然GPU可以接受较高的延迟,但其高带宽特性使得在并行计算时能够有效地处理海量数据。
-
控制与运算:
- CPU:在CPU中,分支控制和逻辑运算是常见的操作,能够高效处理复杂的控制流和决策逻辑。
- GPU:在GPU中,分支控制和复杂的逻辑运算被视为奢侈品,因为GPU的设计更倾向于执行大量相同或相似的操作(SIMD:单指令多数据)。这使得GPU在处理并行计算任务时,尤其是在图形渲染和科学计算等领域,表现出色。
-
性能对比:
- 在面对海量数据并发计算的场景时,GPU的并行处理能力使其在性能上比CPU快几个数量级。这使得GPU成为深度学习、图形渲染、物理模拟等领域的首选计算平台。
总结
CPU和GPU在设计理念和应用场景上有着显著的差异。CPU适合处理复杂的逻辑和低延迟任务,而GPU则在处理大规模并行计算时表现优异。了解这些差异有助于开发者在选择计算平台时做出更明智的决策。
以下是CPU和GPU之间差异的表格总结:
特性 | CPU | GPU |
---|---|---|
延迟容忍度 | 低 | 高 |
并行目标 | 任务(Task) | 数据(Data) |
核心架构 | 多线程核心 | SIMT核心 |
线程数量级别 | 10 | 10000 |
吞吐量 | 低 | 高 |
缓存需求量 | 高 | 低 |
线程独立性 | 低 | 高 |
解释
-
延迟容忍度:CPU对延迟的敏感度较高,适合需要快速响应的任务;而GPU可以容忍较高的延迟,适合处理大量并行计算。
-
并行目标:CPU主要针对任务级别的并行处理,适合复杂的逻辑和控制流;GPU则专注于数据级别的并行处理,适合执行相同操作的多个数据元素。
-
核心架构:CPU采用多线程核心设计,能够高效处理多任务;GPU则使用SIMT(Single Instruction, Multiple Threads)核心,能够同时处理大量线程。
-
线程数量级别:CPU通常处理的线程数量在10个左右,而GPU能够同时处理的线程数量可达到10000个以上。
-
吞吐量:CPU的吞吐量相对较低,适合处理复杂的计算;GPU的吞吐量高,能够快速处理大量数据。
-
缓存需求量:CPU对缓存的需求量较高,以减少内存访问延迟;GPU对缓存的需求量较低,因为其设计更侧重于高带宽的数据传输。
-
线程独立性:CPU中的线程通常相互依赖,适合处理需要复杂控制的任务;GPU中的线程则高度独立,适合执行大量相似的操作。
这个表格清晰地展示了CPU和GPU在设计理念、架构和应用场景上的根本差异,帮助理解它们各自的优势和适用领域。
CPU指令的执行过程
CPU的指令执行过程通常可以分为以下五个经典的流水线阶段:
-
Instruction Fetch(取指令):
- 从指令缓存(I-Cache)中取出指令,并将其放入指令寄存器中。
-
Instruction Decode(指令解码):
- 解码指令,并通过寄存器文件(Register File)获取指令的源操作数。
-
Execute(执行指令):
- 执行解码后的指令。
-
Memory Access(内存访问):
- 如果指令需要访问存储器(如load/store指令),则通过数据缓存(D-Cache)进行数据的读取或写入。对于不需要访问存储器的指令,此阶段不执行任何操作。
-
Register Write Back(寄存器写回):
- 将指令执行的结果写入目的寄存器。
延迟处理
-
主存访问延迟:
- 无论是CPU还是GPU,访问主存都会出现较大的延迟。CPU通过以下手段来遮掩延迟:
- 大容量高速缓存:CPU的缓存容量通常比GPU大,例如GPU没有L3缓存。
- 分支预测:现代CPU的分支预测准确率可达90%以上,能够提高流水线的执行性能。
- 乱序执行(Out-of-Order Execution):CPU会在保证执行结果正确性的基础上,调整指令的执行顺序,以减少执行等待和提升管线性能。
- 无论是CPU还是GPU,访问主存都会出现较大的延迟。CPU通过以下手段来遮掩延迟:
-
GPU的延迟处理:
- GPU采用不同的策略,通过切换线程(Warp)来规避指令延迟带来的处理单元停顿。GPU的线程切换几乎没有上下文切换开销,因为其寄存器数量较多,切换时不需要保存和恢复上下文。
超标量设计与线程切换
-
超标量设计(Super Scalar):
- 现代CPU能够同时发射多条指令,实现指令的并行计算,而不是串行执行,从而更好地利用计算单元。
-
线程切换:
- CPU的线程切换会有明显的上下文切换开销,CPU会尽量避免频繁的线程切换。相对而言,GPU可以通过零成本的线程切换来遮掩延迟。
超线程技术
- 超线程技术(Hyper-Threading):
- Intel CPU采用超线程技术,准备两套寄存器,使得一个核心可以在两个线程之间低成本切换。尽管如此,CPU的寄存器数量仍然有限,切换并不总能降低延迟,且无法准确控制每个线程的执行时间。因此,在许多游戏和高性能计算程序中,超线程功能常常被关闭。
总结
CPU和GPU在指令执行、延迟处理、线程管理等方面有着显著的差异。CPU通过复杂的流水线设计、缓存机制和预测技术来提高性能,而GPU则通过大量的并行计算和高效的线程切换来应对延迟。这些设计理念和技术使得CPU和GPU在各自的应用场景中发挥出最佳性能。
GPU渲染过程
GPU的渲染过程是一个复杂的管线流程,通常被称为渲染管线。以下是该过程的详细描述,结合经典的渲染管线执行步骤。
1. 渲染命令的发出
- 图形API:应用程序通过图形API(如DirectX、OpenGL、Vulkan、Metal)发出渲染命令。
- 驱动程序:这些命令通过驱动程序传输数据给GPU。
2. 主机接口与前端处理
- 主机接口(Host Interface):GPU通过主机接口接收这些渲染命令。
- 前端(Front End):前端负责解析和处理这些命令,为后续的渲染过程做准备。
3. 顶点着色器的执行
- SM(Streaming Multiprocessor):负责执行顶点着色器。现代GPU采用统一着色器架构(Unified Shader Architecture),即顶点着色器和像素着色器使用相同的处理核心。
- 负载均衡:这种架构使得GPU能够更好地进行负载均衡,以适应不同的工作场景(如顶点任务重或像素任务重)。
4. 三角形处理与裁剪
- 裁剪:处理过的三角形会被裁剪,确保只渲染在视口内的部分。
- 光栅化引擎:裁剪后的三角形会被分配给光栅化引擎。
5. 光栅化
- 光栅化阶段:在光栅化阶段,三角形被离散化为与屏幕对应的栅格信息,生成片元(Fragment)。
6. Early Z剔除与像素线程生成
- Early Z剔除:光栅化后的片元经过Early Z剔除,减少不必要的像素处理。
- 像素线程:生成像素线程,32个线程组成一个线程束(Warp),这是GPU计算核心的最小工作单元。
7. 像素着色器的执行
- 像素着色器:在SM中执行像素着色器。一个Warp中执行的指令是相同的,但处理的数据是不同的(SIMD/SIMT)。
8. ROP(Raster Operations)
- 数据交给ROP:执行完像素着色器后,数据会交给ROP。
- 排序过程:由于像素着色器的执行时间可能不同,ROP内部会有一个排序过程,以确保执行ROP的顺序与原始API的调用顺序一致。
- ROP单元:ROP内部有多个ROP单元,负责处理深度测试和Framebuffer的混合。
9. 深度测试与颜色写入
- 原子操作:深度测试和颜色写入必须是原子操作,以避免在同一像素点上不同三角形之间的冲突和错误。
总结
GPU的渲染过程是一个高度并行化的流程,涉及多个阶段,从命令的发出到最终的像素输出。通过统一着色器架构、光栅化、Early Z剔除、像素着色器执行和ROP处理,GPU能够高效地处理复杂的图形渲染任务。这种设计使得GPU在处理大量并行计算时表现出色,适合现代图形应用和游戏的需求。
桌面端与移动端的内存结构差异
在现代计算设备中,桌面端和移动端的内存结构存在显著差异,主要体现在CPU和GPU的内存管理方式上。以下是对这两种架构的详细比较。
1. 内存架构类型
-
桌面端:
- 分离式架构:桌面端通常使用独立显卡,CPU和GPU各自拥有独立的物理内存。这种架构允许GPU使用专用的显存(如GDDR显存),通过独立的北桥(如PCIe)与CPU进行通信。
- 集成显卡:即使是集成显卡,桌面端也通常采用统一内存架构(UMA),但它们的内存区域仍然是分开的。
-
移动端:
- 统一内存架构(UMA):移动设备通常采用统一内存架构,CPU和GPU共享同一物理内存。这种设计使得内存管理更加灵活,操作系统可以动态分配给GPU的显存大小。
- SoC(System on Chip):移动芯片通常是SoC,CPU和GPU等组件集成在同一芯片上,无法像桌面端那样为显卡配备独立的显存。
2. 内存管理与数据传输
-
桌面端:
- 独立显存的优势:GPU可以对Buffer或Texture进行进一步优化,使用更适合GPU访问的内存布局。显存中存储的数据可能经过优化处理,提升性能。
- 数据拷贝:CPU与GPU之间的数据通信通常需要拷贝过程,数据从主内存传输到显存。
-
移动端:
- 共享物理内存的灵活性:虽然CPU和GPU共享同一物理内存,但它们使用的内存区域并不完全相同。GPU管理一块专有区域,仍然需要进行数据拷贝。
- 带宽竞争:由于CPU和GPU共享带宽,可能会导致带宽争用,限制GPU的性能。
3. 零拷贝与真正的UMA
- 真正的UMA:狭义上讲,只有在主机平台或某些特定架构(如苹果M1芯片)中,CPU和GPU能够实现零拷贝数据传输,才算是真正的UMA。在这种情况下,CPU和GPU可以直接访问相同的数据,而无需进行数据拷贝。
- 移动端的共享内存:移动端的共享物理内存架构虽然称为UMA,但实际上仍然需要通过MapBuffer等方式进行数据拷贝,无法实现完全的零拷贝。
4. CUDA的统一虚拟地址与统一内存
- 统一虚拟地址(UVA)与统一内存(UM):CUDA推出的这些技术旨在简化开发者的内存管理负担。它们将内存和显存的虚拟地址统一,但与物理内存的合并或分离无关。
- 开发者便利性:通过这些技术,开发者可以更方便地管理内存,而不必过多关注物理内存的具体分配和管理。
总结
桌面端和移动端的内存结构差异主要体现在内存的分离与共享、数据传输方式以及性能优化上。桌面端的独立显存架构提供了更高的性能和优化空间,而移动端的统一内存架构则在灵活性和集成度上具有优势。理解这些差异对于开发高效的图形应用和优化性能至关重要。
Pixel Quad
在图形渲染的光栅化阶段,Pixel Quad(像素四元组)是一个重要的概念。尽管最终的渲染结果是以单个像素为单位,但光栅化模块输出的单位是2x2的像素组,即Pixel Quad。这种设计有几个重要的原因和影响:
1. 计算效率
- ddx 和 ddy 的计算:在像素着色器(Pixel Shader, PS)中,计算像素的梯度(如ddx和ddy)是非常重要的,尤其是在选择合适的mipmap层级时。单个像素无法提供足够的信息来进行这些计算,而Pixel Quad作为一个2x2的像素组,可以提供更丰富的上下文信息,使得GPU能够更有效地进行这些计算。
2. Early Z 判定
- 最小单位:进行Early Z判定时,最小的处理单位也是Pixel Quad。这意味着即使一个三角形只覆盖了Quad中的一个像素,整个Quad中的四个像素都需要执行像素着色器。这种设计确保了Z值的早期测试能够在更大范围内进行,从而提高了渲染效率。
3. 辅助像素的概念
- 辅助像素:在一个Pixel Quad中,未被三角形覆盖的像素被称为“辅助像素”。对于较小的三角形,辅助像素的比例可能会很高,这会导致性能浪费,因为这些像素虽然在管线内参与计算,但其结果最终会被丢弃。
4. 带宽消耗
- Cache Line 的影响:由于GPU和内存之间存在cache line的概念,数据交换的大小是固定的。即使是被丢弃的辅助像素,通常也不会节省带宽,因为它们会被原样读入和写出。因此,尽管这些像素的计算结果被丢弃,但带宽消耗依然保持不变。
5. 性能优化建议
- 避免小图元的绘制:为了更有效地利用GPU的计算资源和带宽,开发者应尽量避免绘制大量的小图元。小图元会导致高比例的辅助像素,从而浪费计算资源和带宽。通过合并小图元或使用更大的几何体,可以提高渲染效率,充分利用GPU的Warp(线程束)并减少不必要的计算。
总结
Pixel Quad的设计在光栅化阶段中起到了重要的作用,既提高了计算效率,又优化了Z值判定过程。然而,辅助像素的存在也带来了性能浪费,尤其是在处理小图元时。理解这些概念有助于开发者在图形渲染中做出更有效的优化决策,从而提升整体性能。
Early ZS(Early Depth and Stencil Test)技术
Early ZS技术是现代GPU渲染管线中的一个重要优化手段,旨在提高渲染效率,减少不必要的计算。以下是对Early ZS技术的详细分析,包括其工作原理、优势以及影响因素。
1. Early ZS 的工作原理
-
深度测试的传统流程:在传统的渲染管线中,深度测试(Depth Test)通常在像素着色器(Pixel Shader)执行之后进行。此时,GPU会计算每个像素的颜色和深度值,然后进行深度测试,判断该像素是否被遮挡。如果发现该像素被遮挡,GPU会丢弃该像素的计算结果。这种方式会导致大量的无效计算,尤其是在存在重叠的几何体时,称为“overdraw”。
-
Early ZS 的优化:Early ZS技术通过在像素着色器执行之前进行深度测试,能够提前剔除那些被遮挡的像素。具体来说,Early ZS的最小处理单位是像素块(Pixel Quad),而不是单个像素。这样,如果一个Pixel Quad中的深度测试失败,整个Quad的像素都可以被跳过,避免进入耗时的像素着色器计算。
2. Early ZS 的优势
-
减少无效计算:通过提前剔除被遮挡的像素,Early ZS显著减少了需要执行的像素着色器数量,从而提高了渲染性能。
-
提高管线效率:由于减少了不必要的计算,Early ZS可以提高GPU的整体管线效率,使得更多的计算资源可以用于处理有效的像素。
3. 影响 Early ZS 执行的因素
-
Alpha Test 的影响:
- 无法执行 Early Z Write:由于Alpha Test需要在像素着色器执行后才能确定是否丢弃像素,因此在执行Alpha Test时,无法提前写入深度值。这意味着在进行Alpha Test的情况下,Early ZS的优势会受到限制。
- 阻塞管线:如果像素着色器执行后写入深度值,后续相同位置的片元必须等待该结果返回才能继续执行,这可能导致管线阻塞,影响性能。
-
深度修改:如果在像素着色器中修改深度值,Early ZS的效果也会受到影响。因为在这种情况下,深度测试的结果可能会在像素着色器执行后才确定,从而无法利用Early ZS的优势。
-
Alpha to Coverage:使用Alpha to Coverage技术时,Early ZS的执行也会受到影响。这是因为Alpha to Coverage需要在像素着色器中进行计算,导致无法提前进行深度测试。
4. 总结
Early ZS技术通过在像素着色器执行之前进行深度和模板测试,显著提高了渲染效率,减少了无效计算。然而,某些操作(如Alpha Test、深度修改和Alpha to Coverage)可能会影响Early ZS的执行效果。理解这些影响因素对于优化渲染性能至关重要,开发者在设计渲染管线时应尽量避免这些限制,以充分利用Early ZS带来的性能提升。
Mipmap 的概念与应用
Mipmap 是一种用于提高纹理映射效率的技术,广泛应用于计算机图形学和游戏开发中。它通过预计算和存储不同分辨率的纹理图像,来优化纹理的采样和渲染性能。以下是对 Mipmap 的详细分析,包括其工作原理、优势、内存管理以及在 Unity 引擎中的应用。
1. Mipmap 的工作原理
-
多级纹理:Mipmap 是一系列按比例缩小的纹理图像,通常从原始纹理开始,逐级减小到 1x1 像素。每个级别的纹理称为一个 Mipmap Level。
-
选择合适的 Mipmap Level:在渲染过程中,GPU 会根据纹理坐标的偏导数(ddx 和 ddy)来选择合适的 Mipmap Level。这种选择确保了在不同的视距和角度下,纹理的细节能够得到合理的保留,避免了模糊或锯齿现象。
2. Mipmap 的优势
-
节省带宽:虽然 Mipmap 会增加纹理数据的总大小(因为需要存储多个级别的纹理),但它通过提高相邻像素在同一 Cache Line 中的命中率,减少了对主存的访问,从而降低了带宽消耗。高命中率的 Texture Cache 可以显著减少 GPU 访问主存时的延迟。
-
减少 Stall:访问主存通常需要消耗几百个时钟周期,这会导致严重的 Stall。通过提升 Texture Cache 的命中率,Mipmap 可以有效减少这种情况的发生,从而提高渲染性能。
-
性能指标:在 GPU 性能分析中,Texture L1/L2 Cache Missing 是一个重要的指标,通常需要控制在较低的数值,以确保良好的性能。
3. 内存管理与 Texture Streaming
-
内存占用:Mipmap 本身会增加大约 1/3 的内存消耗,因为需要存储多个级别的纹理。然而,开发者可以通过动态控制上传给 GPU 的最高 Mipmap Level 来有效管理内存使用。
-
Unity 的 Texture Streaming:Unity 引擎实现了 Texture Streaming 机制,允许开发者控制纹理的内存占用。通过将不重要的纹理替换为高级别的 Mipmap,Unity 可以在保持固定的纹理内存总量的同时,减少内存占用。当需要重新切换到 Mipmap Level 0 时,可能会经历纹理加载的过程,但这一过程通常是透明的,开发者不会感知到。
-
内存释放:在移动平台上,CPU 和 GPU 共享物理内存,但其内存空间是分离的。当纹理上传到 GPU 后,CPU 端的纹理内存会被释放。对于需要 CPU 读写的纹理(如勾选了 Read/Write Enabled 的纹理),CPU 端的内存不会被释放,这样会导致该纹理在 CPU 和 GPU 端各占用一份内存。
4. 总结
Mipmap 技术通过提供多级纹理,优化了纹理的采样和渲染性能,显著提高了 Texture Cache 的命中率,减少了带宽消耗和主存访问延迟。尽管 Mipmap 会增加内存占用,但通过动态控制最高 Mipmap Level 和使用 Texture Streaming,开发者可以有效管理内存使用。在 Unity 引擎中,Texture Streaming 机制使得纹理的加载和内存管理更加灵活,提升了游戏的整体性能和用户体验。
纹理采样与纹理过滤
纹理采样是计算机图形学中将纹理图像应用于几何体表面的过程,而纹理过滤则是决定如何从纹理中获取颜色值的技术。不同的过滤模式会影响最终渲染效果的质量和性能。以下是对几种常见纹理过滤模式的详细介绍。
1. 纹理过滤模式
-
临近点采样(Nearest Point Sampling):
- 原理:临近点采样是最简单的纹理过滤方法,它直接选择与纹理坐标最接近的像素值。这种方法不会进行任何插值计算。
- 优点:计算简单,性能高效,适合对性能要求极高的场景。
- 缺点:可能导致锯齿状的边缘和不平滑的纹理效果,尤其是在缩放或旋转时。
-
双线性插值(Bilinear Interpolation):
- 原理:双线性插值通过在纹理坐标周围的四个像素之间进行线性插值来计算最终的颜色值。它考虑了水平和垂直两个方向的插值。
- 优点:相较于临近点采样,双线性插值提供了更平滑的纹理效果,减少了锯齿现象。
- 性能:现代GPU通常可以在一个周期内完成一个双线性采样,较新的高端GPU(如Mali-G78)甚至可以在0.25个周期内完成一个双线性采样,意味着它可以在一个周期内完成一个像素块(Quad)的采样。
-
三线性插值(Trilinear Interpolation):
- 原理:三线性插值在双线性插值的基础上,进一步考虑了不同 Mipmap 级别之间的插值。它需要从两个 Mipmap 级别中采样,并对这两个级别的结果进行插值。
- 优点:提供了更平滑的纹理效果,尤其是在视距变化时,能够有效减少 Mipmap 级别切换带来的视觉不适。
- 性能:由于需要采样两个 Mipmap 级别,三线性插值的开销是双线性插值的两倍,通常需要两个周期来完成一个采样。
-
各向异性过滤(Anisotropic Filtering):
- 原理:各向异性过滤是一种高级纹理过滤技术,能够在不同的视角下提供更高质量的纹理采样。它通过在多个方向上进行采样,考虑了纹理在斜视角下的失真。
- 优点:显著提高了在斜视角下的纹理质量,减少了模糊和失真现象。
- 性能:各向异性过滤的开销与所选的各向异性级别(N倍)成正比,N越大,性能开销越高。
2. 性能与应用
-
性能比较:
- 临近点采样和双线性插值在性能上相对接近,适合对性能要求较高的场景。
- 三线性插值虽然提供了更好的视觉效果,但在性能上需要更多的计算资源。
- 各向异性过滤在高质量渲染中非常重要,但其开销也相对较高,适合在需要高质量纹理的场景中使用。
-
应用场景:
- 临近点采样:适用于像素艺术、2D游戏或对性能要求极高的场景。
- 双线性插值:广泛应用于大多数3D游戏和应用中,提供了良好的平衡。
- 三线性插值:适合需要高质量纹理的场景,尤其是在视距变化较大的情况下。
- 各向异性过滤:在需要高质量纹理的场景中(如开放世界游戏、复杂场景等)非常重要。
3. 总结
纹理采样和过滤是影响渲染质量和性能的关键因素。选择合适的纹理过滤模式可以在视觉效果和性能之间取得良好的平衡。开发者应根据具体的应用场景和性能需求,合理选择纹理过滤技术,以实现最佳的渲染效果。
从硬件角度理解GPU的执行逻辑
GPU(图形处理单元)是专门设计用于高效处理图形和图像的硬件,其执行逻辑与CPU(中央处理单元)有显著不同。以下是对GPU中可编程元件和固定管线元件的详细分析,以及Early Z、Late Z、Blend等操作的执行逻辑。
1. 可编程元件与固定管线元件
-
可编程元件:
- 顶点处理:在GPU中,顶点着色器是可编程的,允许开发者自定义如何处理每个顶点的属性(如位置、颜色、法线等)。这些指令在Shader Core中执行。
- 像素处理:片段着色器(或像素着色器)同样是可编程的,负责计算每个片元的最终颜色值。
-
固定管线元件:
- 光栅化:光栅化是将几何图形转换为片元的过程,这一过程是不可编程的,由光栅化引擎负责。光栅化引擎将三角形等几何图形转换为屏幕上的像素。
- ROP(光栅操作单元):负责执行Early Z、Late Z和Blend等操作。ROP是固定管线的一部分,专门处理与像素输出相关的任务。
2. Early Z与Late Z的执行逻辑
-
Early Z:
- 原理:Early Z测试是在片元着色器执行之前进行的深度测试。它通过检查片元的深度值,决定该片元是否应该被绘制到帧缓冲区中。
- 硬件实现:Early Z的执行是由ROP单元完成的,类似于流水线中的阀门,控制片元是否通过。与软件实现的算法相比,硬件实现的Early Z更高效,因为它可以在片元生成后立即进行深度测试,避免不必要的计算。
- RenderState的影响:在游戏引擎中,每个drawcall都有对应的RenderState,决定了是否进行AlphaBlend、深度写入等操作。对于硬件而言,图元并不知道当前的RenderState,因此它们会根据当前状态进行处理。
-
Late Z:
- 原理:Late Z测试是在片元着色器执行之后进行的深度测试。此时,片元的颜色值已经计算完成,Late Z会决定是否将该片元的颜色写入帧缓冲区。
- 性能考虑:Late Z通常在需要进行AlphaBlend等操作时使用,因为这些操作需要在片元颜色计算后进行。
3. GPU的乱序执行与保序
-
乱序执行:
- 原理:GPU的计算核心支持乱序执行,允许不同的Warp(工作组)并行执行,且执行时间可能因分支、缓存缺失等因素而异。GPU会尽可能填充任务到计算核心,以提高资源利用率。
- 影响:这种执行方式提高了并行性,但可能导致同一像素的写入顺序不一致。
-
保序机制:
- 保证顺序:尽管GPU支持乱序执行,但同一像素的写入顺序是有保证的。先执行的drawcall的像素一定会先写入到Framebuffer中。
- FIFO队列:不同阶段之间的输出结果通过FIFO(先进先出)队列进行管理,以确保顺序。随着技术的发展,可能会使用其他机制,但最终目标是保持输出的有序性。
- 现实意义:对于半透明物体,保序是至关重要的,因为乱序可能导致错误的渲染结果。对于不透明物体,虽然Depth Test可以保证结果正确,但保序仍然有助于提高性能并缓解Z-fighting(深度冲突)。
总结
从硬件角度看,GPU的执行逻辑是一个复杂的系统,涉及可编程元件和固定管线元件的协同工作。Early Z和Late Z的执行由ROP单元负责,确保了高效的深度测试。GPU的乱序执行与保序机制相结合,既提高了并行处理能力,又保证了渲染结果的正确性。这些设计使得GPU能够在高负载的图形处理任务中保持高效和高质量的输出。