一、显存带宽基础
大家好,我是你们这堂课的主讲人。做了这么多年GPU性能优化,我最大的感触就是——显存带宽,这玩意儿是绕不过去的坎儿。今天咱们就来聊聊,到底什么是显存带宽,它怎么算,又怎么影响你的GPU跑得快不快。
1.1 什么是显存带宽?
说白了,显存带宽就是GPU核心和显存之间,每秒钟能传输多少数据。你可以把它想象成一条高速公路。GPU核心是工厂,显存是仓库。工厂要干活,就得从仓库搬原料、送成品。这条高速公路越宽,车跑得越快,单位时间能运的货就越多。
我经常跟团队里的小朋友说:「算力是肌肉,带宽是血管」。肌肉再发达,血管细得像根吸管,血液供不上,照样跑不动。GPU也是一样,你的计算单元再多、频率再高,数据喂不进去,全是白搭。
核心定义:显存带宽 = GPU核心与显存之间的数据传输速率,单位通常为 GB/s(千兆字节每秒)。
嗯,这里要注意一点:带宽和延迟是两个概念。带宽是「能运多少」,延迟是「运一趟要多久」。咱们这章主要聊带宽,延迟后面会专门讲。
1.2 带宽的计算公式
公式其实很简单,我直接写出来:
显存带宽 = 显存频率 × 显存位宽 × 显存类型系数
拆开来看:
- 显存频率(Memory Clock):单位是 MHz 或 GHz。注意,这里通常指的是有效频率。比如 GDDR6 的显存,实际物理频率可能只有 1750 MHz,但有效频率是 1750 × 4 = 7000 MHz(因为 DDR 技术在每个时钟周期传输 4 次数据)。
- 显存位宽(Memory Bus Width):单位是 bit。这决定了「一次能搬多少数据」。常见的位宽有 128-bit、256-bit、384-bit、1024-bit(HBM)等。位宽越大,相当于高速公路的车道越多。
- 显存类型系数:这个系数取决于显存类型。GDDR5 是 2(因为 DDR 双倍数据率),GDDR5X 是 4,GDDR6 也是 4,HBM2/HBM2E 是 2(但它的位宽特别大)。
举个例子,我手头有一块 RTX 3090,它的参数是:
- 显存频率:1219 MHz(实际物理频率),有效频率 9750 MHz(1219 × 8,因为 GDDR6X 是 8 倍率)
- 显存位宽:384-bit
- 类型:GDDR6X
那么它的带宽就是:
带宽 = 9750 MHz × 384 bit ÷ 8(bit 转 Byte) ÷ 1000(MHz 转 GHz)
= 9750 × 48 ÷ 1000
= 468 GB/s
嗯,实际上 RTX 3090 的带宽标称是 936 GB/s。为什么差了一倍?因为 GDDR6X 用了 PAM4 编码,每个时钟周期能传 4 个 bit,所以系数要再乘 2。你看,细节决定成败,我在项目中就吃过这种亏——算错了带宽,导致预估性能偏差了 30%。
避坑指南:我曾经在评估一个推理卡时,直接拿显存频率 × 位宽 ÷ 8 就完事了。结果发现实际带宽只有理论值的 60%。后来一查,原来是显存控制器有开销,还有 ECC 校验占了一部分。所以,理论带宽只是上限,实际能跑多少,还得看你的访存模式。
1.3 带宽对GPU性能的影响
这个问题,我换个问法:你的模型跑得慢,到底是算力不够,还是带宽不够?
这就要引入一个概念——计算强度(Arithmetic Intensity)。说白了,就是「每读一次数据,要做多少次计算」。如果计算强度高,比如矩阵乘法,那瓶颈通常在算力上。如果计算强度低,比如逐元素操作、Reduce 操作,那瓶颈基本就在带宽上。
我画了一张图,帮你理解这个关系:
你看这张图,横轴是计算强度,纵轴是实际性能。红色虚线是算力上限,蓝色斜线是带宽上限。实际性能,就是取这两条线的较小值——说白了,短板效应。
我举个例子你就明白了:
- 场景一:大矩阵乘法(GEMM)。计算强度很高,比如 100 FLOP/Byte。这时候性能受算力限制,带宽再高也帮不上忙。你换一块带宽翻倍的卡,性能可能只提升 5%。
- 场景二:逐元素加法(Element-wise Add)。计算强度极低,比如 0.5 FLOP/Byte。这时候性能完全被带宽卡死。你算力再高,数据搬不过来,核心只能干等着。我优化过一个模型,把几个逐元素操作融合成一个 kernel,带宽利用率从 30% 提到了 80%,推理速度直接翻倍。
注意:很多人以为买显卡只看算力(TFLOPS)就够了。其实不然。如果你的应用是带宽敏感型的,比如推荐系统、图神经网络、小 batch 推理,那显存带宽比算力更重要。我曾经帮一个客户选型,他非要买算力最高的卡,结果跑他的模型,性能还不如一块带宽更大的中端卡。为什么?因为他的模型全是稀疏操作,算力根本用不上,全卡在带宽上了。
1.4 如何判断你的模型是带宽受限还是算力受限?
方法很简单,用 NVIDIA 的 ncu(Nsight Compute)或者 nvprof 跑一下,看两个指标:
- Memory Throughput(%):显存带宽利用率。如果接近 100%,说明带宽是瓶颈。
- Compute Throughput(%):计算单元利用率。如果接近 100%,说明算力是瓶颈。
如果两个都低,那说明你的代码有问题——要么是访存模式差,要么是线程束发散严重。嗯,这个后面章节会细讲。
我个人的习惯是,拿到一个新模型,先跑一遍 profiler,看一眼这两个指标。如果 Memory Throughput 超过 80%,我就知道该在访存优化上下功夫了。如果 Compute Throughput 超过 80%,那就该考虑算子融合、量化这些手段。
一个小技巧:你可以用「Roofline Model」来快速定位瓶颈。把模型的计算强度和硬件参数画到图上,一眼就能看出是带宽受限还是算力受限。我每次做性能分析,第一件事就是画 Roofline。
1.5 总结
好了,这一章的内容就这些。总结一下:
- 显存带宽是 GPU 性能的命脉,尤其对带宽敏感型应用。
- 带宽 = 频率 × 位宽 × 系数,但实际值往往低于理论值。
- 用 Roofline Model 判断瓶颈,别盲目堆算力。
下一章,我们会深入聊聊显存的物理结构——从 GDDR 到 HBM,不同显存类型对带宽和延迟的影响。嗯,到时候我会分享一些我在 HBM 优化上踩过的坑,保证让你少走弯路。
公众号:蓝海资料掘金营,微信deep3321