LabHub
学习 学习路径 课程

计算机组成

GPU — 不削延迟,而是把吞吐摊宽的设计

在 LabHub 中继续学习

一句话总结

CPU 的目标是让单个线程尽快完成,GPU 则让数万个线程同时运行,以其他线程的工作掩盖内存等待时间。

概念图: GPU 不是降低延迟,而是隐藏延迟的设备 · 流式多处理器(SM) · 线程束(warp) · 分支发散(divergence)。

为什么需要了解这些

CPU 把晶体管用于降低单条执行流的延迟:分支预测、乱序执行和大缓存都在防止当前线程停顿,但扩大这些结构的收益递减。另一种选择是简化控制电路、堆叠算术单元并驻留大量线程;一个线程等待内存时就运行另一个线程。这是 GPU 的设计哲学,所以GPU 不是降低延迟,而是隐藏延迟的设备

工作原理

GPU 由多个流式多处理器(SM) 组成。每个 SM 中,线程按 32 个组成一个线程束(warp) 调度;同一线程束中的线程对各自数据执行相同指令(SIMT)。

由此产生两类性能陷阱。

分支发散(divergence)。 同一线程束中一半走 if、另一半走 else 时,硬件会依次执行两条路径,并暂时禁用不属于该路径的线程。结果正确,但耗时是两条路径之和。

合并访问(coalescing)。 32 个线程读取连续地址,只需少量内存事务;读取分散地址时最坏需要 32 次事务。因此同样的计算只改变索引方式,性能也可能相差数倍。

GPU 的内存层次也不同。SM 中有由程序员显式管理的共享内存。与其等待缓存自动处理,不如主动载入复用数据供多个线程共享。矩阵乘法内核的大部分性能来自这种共享内存分块。

占用率(occupancy) 是实际驻留线程束数与 SM 可同时维持的线程束数之比。占用率低时,没有足够线程掩盖内存等待。但占用率高也不一定更快;大量使用寄存器的内核有时值得牺牲占用率,增加每线程工作量。

实际工作中的表现

AI 推理中 GPU 利用率不到 30% 很常见,原因往往不是算力不足,而是内存带宽。LLM 解码读取巨大权重、与很小的输入相乘后丢弃,算术强度低,处于 roofline 左侧斜坡。此时购买算力更高的芯片也无济于事,应减少读取字节数(量化),或增大批次,让多个请求共享同一次权重读取。

TPU 等加速器给出的另一种答案也是如此:脉动阵列让数据在网格中流动并复用,以最大化每次内存访问的计算量,用通用性换取算术强度。

哪些任务适合 GPU

判断标准有三项。

一次是否有足够多的工作。 GPU 需要运行数万个线程;只有几千个元素时,连启动内核的成本都收不回来。内核启动需数微秒,CPU 往往早已完成。

相对计算量,要传输的数据是否够少。 CPU 与 GPU 内存分离,复制通道远窄于 GPU 内部带宽。若复制时间超过计算时间,使用 GPU 就是纯损失。 正确做法是把数据上传一次后连续在 GPU 上完成多个阶段,而不是每一步都传回 CPU 再上传。

各线程执行的工作是否相同。 每个元素走不同条件分支时,会因分支发散而显著损失收益。因此 GPU 最适合稠密数组上的规则运算。

反过来,不适合 GPU 的是:分支众多的逻辑、追踪指针的数据结构、依赖上一步结果的串行处理,以及每次只做少量计算的短任务。AI 训练与推理适合 GPU,并非因为神秘特性,而是因为它们恰好满足这三项条件。

还有一个实务经验:GPU 服务器性能不佳时,问题常在数据供给端。读取、预处理和上传管线若喂不满 GPU,昂贵的卡大部分时间都在等待。利用率随时间呈锯齿状起伏,就是典型迹象。

后续测验将确认什么

确认你能解释为何“GPU 比 CPU 快”只说对了一半,以及买了 GPU 仍得不到预期性能的典型原因。