2、性能调优基础:理解延迟与吞吐量,计算核心与存储墙的博弈

好,咱们正式开始聊性能调优。很多刚入行的朋友,一上来就盯着峰值算力看——“这个IP有10 TFLOPS,牛啊!”

嗯,我当年也这么干过。直到第一次调一个实际应用,发现跑出来的性能连理论峰值的10%都不到。那时候我才真正意识到:延迟和吞吐量,才是性能调优的两条腿。缺一条,你都跑不起来。

2.1 延迟 vs 吞吐量:两个不同的“快”

先搞清楚这两个概念。说白了:

  • 延迟(Latency):从发请求到拿到结果,花了多少时间。单位通常是纳秒、微秒。
  • 吞吐量(Throughput):单位时间内能处理多少个请求。单位是 ops/s、GB/s。

举个例子。你去食堂打饭:

  • 延迟 = 你从排队到打到饭,花了5分钟。
  • 吞吐量 = 食堂窗口每分钟能打20份饭。

你想想看,如果食堂只有一个窗口,延迟可能很低(没人排队),但吞吐量也低。如果开10个窗口,吞吐量上去了,但每个窗口前可能排长队,延迟反而高了。

在GPU里,这两者经常是矛盾的。我个人习惯是:先看延迟是否满足实时性要求,再看吞吐量能不能喂饱计算单元

核心观点: 延迟是“单次任务”的体验,吞吐量是“整体效率”的体现。调优时,你得搞清楚用户到底要哪个。

2.2 计算核心:理论峰值 vs 实际性能

GPU的计算核心,说白了就是一堆ALU(算术逻辑单元)。它们跑得飞快,但有个前提——你得有数据喂给它们。

理论峰值怎么算?很简单:

理论算力 = 核心数 × 频率 × 每周期操作数

比如一个GPU有4096个核心,频率1.5 GHz,每个周期做2次FMA(乘加运算,算2次浮点操作):

理论算力 = 4096 × 1.5e9 × 2 = 12.288 TFLOPS

看着很猛对吧?但我在项目中遇到过,实际跑一个矩阵乘法,性能只有2 TFLOPS。为什么?因为数据没到位,计算核心在“空转”。

我的经验: 实际性能能达到理论峰值的60%-80%,就算不错了。如果低于30%,你大概率是被存储墙卡住了。

2.3 存储墙:GPU的“阿喀琉斯之踵”

什么是存储墙?就是计算单元跑得太快,内存根本跟不上

你看这组典型数据:

存储层级 延迟(周期) 带宽(GB/s) 容量
寄存器 1 极高 几十KB
L1缓存 10-30 ~1000 几十KB
L2缓存 100-300 ~500 几MB
HBM/GDDR 300-600 ~1000 几GB

看到了吗?从HBM读一次数据,要等300-600个周期。而计算核心一个周期就能做两次运算。这中间的差距,就是存储墙。

我曾经调过一个图像处理IP,核心利用率只有5%。一分析,发现每个像素都要从DDR读三次,写两次。数据搬运的时间,比计算时间多了20倍。这就是典型的“存储墙”问题。

注意: 存储墙不是靠堆带宽就能解决的。带宽再高,延迟摆在那里。你得靠数据复用流水线隐藏来绕过它。

2.4 计算核心 vs 存储墙:一场博弈

好,现在我们把两边摆在一起看:

  • 计算核心:想要数据,越快越好,越多越好。
  • 存储墙:给数据,但慢,而且一次给不了太多。

这场博弈的胜负手,在于计算强度(Arithmetic Intensity)。说白了就是:

计算强度 = 总计算量(FLOPs) / 总数据搬运量(Bytes)

单位是 FLOPs/Byte。这个值越高,说明你的计算越“密集”,越不容易被存储墙卡住。

举个例子:

  • 向量加法:读两个向量,写一个向量。计算强度很低,约 0.5 FLOPs/Byte。这种就是“带宽敏感型”。
  • 矩阵乘法:大量数据复用。计算强度可以做到几十甚至上百 FLOPs/Byte。这种就是“计算敏感型”。

我个人的调优原则是:先算计算强度,再看它落在存储墙的哪一侧

关键判断:

  • 如果计算强度 < 存储墙的“拐点”,你就是被带宽限制的。优化方向:减少数据搬运、提高数据复用。
  • 如果计算强度 > 拐点,你就是被计算限制的。优化方向:提高并行度、减少指令依赖。

2.5 实战:如何找到你的“拐点”

每个GPU都有一个“拐点”计算强度。怎么算?

拐点计算强度 = 理论算力(FLOPs) / 内存带宽(Bytes/s)

比如一个GPU:

  • 理论算力:12 TFLOPS
  • 内存带宽:1 TB/s
拐点 = 12e12 / 1e12 = 12 FLOPs/Byte

这意味着:如果你的算法计算强度低于12,性能就被带宽卡住。高于12,才可能发挥出计算核心的实力。

嗯,这里要注意:这个拐点只是理论值。实际中,还有缓存命中率、指令调度效率等因素。但用它做初步判断,足够了。

避坑指南: 我曾经有一个项目,计算强度算出来是15,高于拐点。但实际性能还是上不去。后来发现是L1缓存频繁miss,数据在L1和L2之间来回倒腾。所以,别只看理论拐点,还要看实际访存模式

2.6 小结:调优的“第一性原理”

说了这么多,其实就一句话:性能调优,本质是让计算核心和存储墙“和解”

  • 理解延迟和吞吐量,你才知道瓶颈在哪。
  • 理解计算强度和拐点,你才知道往哪个方向优化。

我每次拿到一个新IP,第一件事就是画一张“计算强度 vs 性能”的图。看看当前的点落在哪,然后决定是改算法、调数据布局,还是改硬件配置。

下一章,我们会深入聊如何用Roofline模型来做这件事。那是一个更系统、更直观的方法。到时候,你会发现自己对性能的理解,又上了一个台阶。

记住: 存储墙不会消失,但你可以学会和它共舞。