深入解密GPU 内存带宽

172 阅读4分钟

“在现代 3D 渲染中,GPU 的性能瓶颈通常是内存带宽,而不是计算能力。”  —— NVIDIA Ampere Architecture Whitepaper换句话说, 随着 GPU 计算性能的快速增长,内存带宽的增长速度滞后,导致内存带宽成为现代 GPU 的主要性能瓶颈
接下来看一组数据对比:

内存带宽 VS 计算能力:

GPU 架构计算能力(TFLOPS)内存带宽(GB/s)计算/带宽增长比
NVIDIA Kepler4.528816x
NVIDIA Pascal1148422x
NVIDIA Ampere3076839x

从表中可以看出,GPU 的计算性能提升速度远快于内存带宽的增长速度

然后回过头再理解开头那句话就明了了, 在 现代GPU 的发展中, 由于 计算能力的增长速度 远远快于 内存带宽的增长速度, 所以 内存带宽 通常是 现代 3D 渲染的性能瓶颈.

那么, 有哪些缓解 内存带宽 的策略呢?

这个可以先放在脑中思考三秒钟, 俗话说得好, 想要找到 how 需要弄明白 what, 可以简单了解一下 内存带宽? (了解的同学可以跳过这部分)

内存带宽 指的是 GPU 每秒钟从显存(VRAM)读取或写入数据的最大速度,通常用 GB/s(GigaBytes per second)  表示。它是 GPU 数据传输能力的衡量标准,对 GPU 在 3D 渲染、AI 推理、科学计算 等应用中的性能至关重要。

内存带宽(GB/s)=总线宽度(bit)×内存频率(GHz)× 传输效率 / 8

简单来说, 内存带宽 决定了 GPU 在单位时间内可以访问多少数据.

内存带宽越高, GPU可以越快的从现存中获取所需的数据,从而减少访问数据的瓶颈.

那么, 内存带宽在 GPU 中起到了什么作用?

由于在 3D 渲染 或 Real-Time Rendering 中, GPU需要不断的从显存中读取数据, 如 顶点数据(position, normal, texcoord, color等), 索引数据(三角形的顶点索引), 纹理数据(贴图, 材质等), 着色器代码帧缓冲区数据.

划重点, GPU 的计算单元(CUDA cores、ALUs 等)只能在 数据准备就绪 的情况下执行计算。因此,如果 内存带宽不足,即使 GPU 有非常强大的计算能力,也会因为数据访问速度跟不上而导致性能瓶颈。

这也是平时渲染大场景时会出现卡帧的根本原因.

回到上个问题, 缓解 内存带宽的策略有哪些? 

目前从网上搜索来看, 总结了以下几个方案:

1. 使用更高带宽的显存技术

  • GDDR6 → GDDR6X → HBM2e → HBM3
    HBM(High Bandwidth Memory)提供的内存带宽远高于传统 GDDR 显存。
显存类型内存频率(GHz)总线宽度(bit)带宽(GB/s)
GDDR614-18192-384336-768
GDDR6X19-21320-384760-1008
HBM2e3.24096819-1555
HBM33.651202048+

** **

2. 优化内存访问模式

  • 减少内存访问的随机性
    通过优化数据结构和算法,使 GPU 尽量按 顺序访问内存,减少缓存未命中次数。

3. 使用压缩技术

  • 纹理压缩(如 KTX2、DXT、ASTC)

  • 顶点数据压缩

  • 帧缓冲区压缩

4. 批量处理和减少状态切换

    通过合并小批量的Draw Calls, 减少内存访问次数, 来避免 GPU 每次只处理少量数据或频繁切换状态导致的 缓存清空显存访问增加等问题。使用多纹理绑定 和 实例化渲染 来减少 纹理, 着色器的切换次数。

5. 利用 GPU 缓存机制

  • 顶点缓存(Vertex Cache) : 优化 顶点索引数组, 提高 Post-Vertex Cache的命中率, 及 通过 Pre-Vertex Cache 优化 缓存顶点属性数据, 减少对显存的读取次数, 减少重复计算。

  • 纹理缓存(Texture Cache): 通过 Texture Cache, 可以减少纹理数据的显存读取次数。

    

上面的方案并不完整, 每个模块都可以详细补充, 但总结来说: 缓解 GPU 内存带宽瓶颈的核心策略是减少显存的访问次数和数据传输量, 同时提高内存访问的效率和缓存命中率

本文只是浅显的介绍了下 内存带宽, 如有缺失不足之处, 还请读者多多包涵, 多多指正。图片图片图片

后面会深入解析缓解内存带宽的各个策略, 从后往前的顺序, 由浅入深介绍3D渲染优化及GPU最佳实践。

下一篇: 缓解GPU内存带宽 - 顶点缓存

在渲染一个高精度 3D 模型时,顶点着色器可能需要重复处理数百万个顶点。如果 GPU 能记住已经处理过的顶点结果,就能大幅减少计算量。这种记忆机制就是顶点缓存