Memory Types of Discrete GPUs
Memory types of discrete GPUs – RasterGrid | Software Consultancy
一、带宽:VRAM 与系统内存的根本差异
1.1 为什么独立 GPU 需要专用显存
- 独立 GPU 拥有自己的 专用显存(VRAM) ,显存本身以及它与 GPU 之间的连接都针对 最大带宽 进行了优化
- 这是独立 GPU 相比集成 GPU 性能显著更高的根本原因——额外的带宽使 GPU 能够 扩展到更高的核心数量
- 与 CPU 形成对比:CPU 核心数较少,更优先考虑 低延迟 而非纯带宽;GPU 核心数众多,需要用 高带宽 持续喂数据
1.2 各类内存带宽对比
| 内存类型 | 每引脚事务率 | 总线宽度 | 带宽 |
|---|---|---|---|
| DDR4 (系统内存) | ~3.2 GT/s | 64-bit(单通道)/ 128-bit(双通道) | ~25.6 / ~51.2 GB/s |
| GDDR5 | ~8 GT/s | 128 / 256 / 384-bit | ~128 / ~256 / ~384 GB/s |
| GDDR6 | ~16 GT/s | 128 / 192 / 256-bit | ~256 / ~384 / ~512 GB/s |
| HBM | ~1 GT/s | 2048 / 3072 / 4096-bit | ~256 / ~384 / ~512 GB/s |
| HBM2 | ~2 GT/s | 2048 / 3072 / 4096-bit | ~512 / ~768 / ~1024 GB/s |
核心要点: GPU 使用 更宽的总线 和 带宽优化的显存芯片 ,有效带宽比系统内存高 约一个数量级 。
1.3 PCIe 总线带宽——跨设备通信的瓶颈
GPU 通常通过 PCIe x16 连接器连接到主板,但实际可用的 PCIe 版本和通道数取决于 CPU、主板、PCIe 插槽和 GPU 四者的 最小公倍数 。
| PCIe 版本 | 每通道事务率 | 通道数 | 带宽(单向) |
|---|---|---|---|
| PCIe 3.0 | 8 GT/s | x4 / x8 / x16 | ~4 / ~8 / ~16 GB/s |
| PCIe 4.0 | 16 GT/s | x4 / x8 / x16 | ~8 / ~16 / ~32 GB/s |
注:每条通道支持 双向通信 ;实际有效速率因 128b/130b 编码 开销而略低。
关键结论: PCIe 带宽远低于 GPU 访问本地 VRAM 的带宽(如 PCIe 4.0 x16 约 32 GB/s vs GDDR6 256-bit 约 512 GB/s),因此 数据放置位置 对性能有巨大影响。
二、内存访问模型:四种图形内存类型
2.1 系统整体内存拓扑
在独立 GPU 系统中,CPU 和 GPU 各自有本地内存,同时可以通过 PCIe 总线 双向访问 对方的内存:
- GPU 可访问的内存:
- 本地内存(Local Memory / VRAM) :通过 GPU 自身的宽总线访问
- 远程内存(Remote Memory / GPU 可见的系统 RAM) :通过 PCIe 总线访问
- CPU 可访问的内存:
- 系统 RAM(本地)
- CPU 可见的 VRAM 部分 :通过 PCIe 总线访问(这正是 Smart Access Memory 的关键所在)
2.2 缓存行为的关键差异
- GPU 遵循 更宽松的缓存一致性规则 ,追求更高性能,通常 缓存所有内存访问
- CPU 对 GPU 内存的访问通常 不缓存 ,只有远程缓存内存(Remote Cached Memory)例外
2.3 四种图形内存类型
| 内存类型 | 说明 | GPU 是否缓存 | CPU 是否缓存 |
|---|---|---|---|
| Local Visible Memory | CPU 可直接访问的 VRAM | ✅ | ❌ |
| Local Invisible Memory | CPU 不可直接访问的 VRAM | ✅ | ❌ |
| Remote Cached Memory | GPU 可访问、CPU 会缓存的系统内存 | ✅ | ✅ |
| Remote Uncached Memory | GPU 可访问、CPU 不缓存的系统内存 | ✅ | ❌ |
重要影响:
- CPU 从 非缓存内存 读取显著更慢
- CPU 缓存的内存(Remote Cached)与 GPU 之间可能需要 CPU 缓存刷新/失效操作 或 嗅探协议 来维持一致性
三、延迟:各内存类型的读取延迟
3.1 实测数据(Ryzen 5 3600X + Radeon RX 580,PCIe 3.0 x16)
| 内存类型 | CPU 读取延迟 | GPU 读取延迟 |
|---|---|---|
| GPU 本地(VRAM) | ~1200 ns(最高可达 ~1900 ns) | ~340 ns(L2 命中 ~150 ns) |
| 远程缓存(Remote Cached) | ~100 ns(L1/L2/L3 命中时 ~1/3/9 ns) | ~1100 ns(L2 命中 ~150 ns) |
| 远程非缓存(Remote Uncached) | ~115 ns | ~1100 ns(L2 命中 ~150 ns) |
3.2 两个关键结论
- VRAM 延迟高于系统内存 :这与 GPU 内存系统 优化吞吐量、牺牲延迟 的设计一致
- 通过 PCIe 总线访问显著增加延迟 :无论是 CPU 读 VRAM 还是 GPU 读系统内存,跨总线延迟都大幅增加
四、可调整 BAR(Resizable BAR)与 AMD Smart Access Memory
4.1 BAR 是什么
- PCIe 设备需要通过 基地址寄存器(Base Address Registers,BAR) 映射到系统的 I/O 端口或 内存地址空间 ,驱动程序才能与硬件通信
- Local Visible Memory 的大小由 BAR 配置决定
4.2 传统限制:256MB 窗口
- 传统上,GPU 的显存 BAR 被限制在 256MB ——无论显卡有多少 VRAM,CPU 只能看到其中 256MB 的窗口
- 早期 API(如 OpenGL)甚至不让应用程序显式选择内存类型,完全由驱动决定
- Vulkan 等新 API 暴露了各个内存类型,给开发者完全控制权
- AMD 从一开始就暴露了 Local Visible Memory
- NVIDIA 直到 2020 年才跟进
4.3 为什么等了这么久
- Resizable BAR 自 2008 年 就是 PCIe 规范的一部分
- 当时 32 位操作系统仍然普遍,从 4GB 地址空间中拿出超过 256MB 给显存不现实
- 更主要的原因:硬件/固件/软件栈各层缺乏适当支持(如 Windows 支持直到最近才到来)
4.4 Smart Access Memory 的本质
- AMD 率先启用了 Resizable BAR 支持(初期仅限最新显卡系列)
- 技术本身 没有专有性 ,只是在 BIOS、操作系统、驱动等各层启用已有功能
- NVIDIA 也计划推出自己的版本
- 未来趋势 :所有厂商、所有平台的独立 GPU 都将在 Vulkan 等 API 中暴露 整个 VRAM 作为 Local Visible Memory
"Local Invisible Memory 的时代即将终结"
五、性能收益分析
5.1 核心问题:CPU 每帧动态生成大量数据
游戏/图形应用中,大量输入数据由 CPU 每帧动态生成 :
- 逐帧/逐对象常量数据 (变换矩阵等)
- 动态几何数据
- 流式资源
- 其他需要写入 GPU 可访问内存的数据
理想选择 :直接写入 Local Visible Memory ——写操作不太关心延迟,且数据立即在 VRAM 中可用,GPU 后续读取性能最佳。
5.2 当 256MB 窗口耗尽时的两种降级方案
方案一:使用远程内存(通常是 Remote Uncached)
- 缺点 :GPU 每次读取都受 PCIe 总线 带宽和延迟 限制
- 对小数据(如逐帧常量)可接受 :
- PCIe 带宽不是瓶颈
- 数据足够小且频繁使用时会留在 GPU 缓存中,延迟可以被众多线程分摊
- 但首次访问时可能有 数千线程阻塞等待数据到达 ,且数据可能在帧处理过程中被 多次驱逐出缓存
方案二:先写入远程内存,再用 GPU DMA 拷贝到 Local Invisible Memory
- 缺点 :
- 需要 额外拷贝 操作
- 即使使用 GPU 内置 DMA 引擎不占用 GPU 核心时间,仍需等待完成
- 可能需要 额外同步操作
- 内存需求至少临时翻倍
- 对大数据集更优 :
- DMA 传输连续数据流能更好利用 PCIe 带宽
- 等待期间依赖线程不占用 GPU 核心的 宝贵寄存器空间 ,允许更多无依赖工作执行
5.3 驱动内部资源同样受益
不仅应用程序分配的内存,图形驱动自身 也有资源需要存储在 GPU 可访问内存中:
- 内部资源
- 描述符表/池 (通常直接从显存读取)
- 命令缓冲区内存 (重中之重)
如果驱动使用 Local Visible Memory 存放这些资源,256MB 窗口会更快耗尽;如果窗口已满,驱动也必须使用上述降级方案。Resizable BAR 同样惠及这些驱动内部资源。
六、例外情况:什么时候不应该用 VRAM
6.1 超大数据集
- VRAM 装不下时,远程内存作为 后备存储
- 更好的做法:把 VRAM 当作活跃(或性能关键)数据集的 缓存 使用
6.2 纹理上传的暂存缓冲区(Staging Buffer)
- 纹理数据通常需要从设备无关格式转换为 GPU 支持的 最优平铺格式(Tiling)
- 推荐做法 :
- CPU 将 Pitch-Linear 暂存纹理数据写入 Remote Uncached Memory
- 用显卡 DMA 引擎执行 线性到平铺拷贝(Linear-to-Tiled Copy) 上传到 VRAM
- 原因 :数据无论如何需过 PCIe 一次,DMA 引擎可以更高效地完成转换,且 不消耗 CPU/GPU 处理核心时间
6.3 数据回读(Read-back)
- 非平凡的数据回读 (纹理或缓冲区):使用 Remote Cached Memory
- 利用 CPU 缓存可比非缓存快 数个数量级
- 小数据回读 (计数器值、查询结果):使用 Uncached Memory 更优
- 可以 避免 CPU 缓存失效操作 的开销
七、总结与关键要点
| 要点 | 说明 |
|---|---|
| VRAM 带宽远超系统内存 | 约一个数量级的差距 |
| PCIe 是跨设备访问的瓶颈 | PCIe 4.0 x16 ~32 GB/s vs GDDR6 ~512 GB/s |
| 四种图形内存类型 | Local Visible / Invisible + Remote Cached / Uncached |
| GPU 缓存一切,CPU 仅缓存 Remote Cached | 缓存行为差异影响使用策略 |
| Resizable BAR(Smart Access Memory) | 让 CPU 看到整个 VRAM,消除 256MB 窗口限制 |
| 核心收益 | 消除降级方案带来的额外拷贝/同步/带宽/延迟开销 |
| 不是万能药 | 纹理上传用 staging buffer、数据回读用 Remote Cached 等场景仍需合理选择 |
最终结论 :Resizable BAR 虽不是独立 GPU 技术的"圣杯",但对应用开发者而言是 真正的游戏规则改变者 ——开发者现在拥有了更大的自由度来将数据放置在合适的内存池中,同时消除了以往为实现这一目标所需的不必要拷贝。