应对内存带宽限制
如 [UarchMainmemory] 中所述,处理器通过内存总线(memory bus)从内存中获取数据。采用最新的 DDR5 内存技术,每通道最大理论内存带宽为 51.2 GB/s。现代系统拥有多个内存通道;例如,典型的笔记本电脑通常有两个内存通道,而服务器系统可以有 4 到 12 个通道。看起来即使是笔记本电脑每秒也能传输大量数据,但实际上,内存带宽在许多应用程序中成为限制因素。
我们应该记住,内存通道在系统中的所有内核之间共享。一旦许多内核同时进行内存密集型活动,流经内存总线的流量可能会拥塞。这可能导致内存请求的等待时间增加。现代系统的设计是为了同时容纳多个内存密集型线程,因此通常需要多个线程才能使内存带宽饱和。新兴的 AI 工作负载以"极度消耗内存"和高度并行化著称,因此内存带宽是它们的首要瓶颈。
解决内存带宽限制的第一步是确定最大理论和预期内存带宽。理论最大内存带宽可以从内存技术规格计算得出,如我们在 [roofline] 中所示。预期内存带宽可以使用 Intel Memory Latency Checker 或 lmbench 等工具测量,我们在 [MemLatBw] 中讨论过这些工具。Intel VTune 可以在分析的应用程序启动之前自动测量内存带宽。
第二步是在应用程序运行时测量内存带宽利用率。如果内存流量接近最大测量带宽,则应用程序的性能很可能受到内存带宽的限制。绘制内存带宽利用率随时间的变化图是个好主意,以查看是否有不同的阶段出现内存密集度的峰值或低谷。如果在分析配置中勾选"评估最大 DRAM 带宽"复选框,Intel VTune 可以提供此类图表。
如果您已确定应用程序受内存带宽限制,第一个建议是查看是否可以降低应用程序的内存密集度。这并不总是可能的,但您可以考虑禁用应用程序中一些内存密集型功能、在运行时重新计算数据而不是缓存结果,或压缩数据。在 AI 领域,大多数大型语言模型(Large Language Models,LLMs)以 fp32 精度提供,这意味着每个参数占用 4 字节。最大的性能提升可以通过量化(quantization)技术实现,将参数精度降至 fp16 或 int8,这将分别将内存流量降低 2 倍或 4 倍。有时甚至使用 4 位和 5 位量化,以减少内存流量并在推理性能和质量之间取得适当平衡。
值得注意的是,对于使可用内存带宽饱和的工作负载,代码优化的作用不像计算密集型(compute-bound)工作负载那样大。对于计算密集型应用程序,向量化等代码优化通常能带来较大的性能提升。然而,对于内存受限的工作负载,向量化可能没有类似效果,因为处理器无法取得进展,原因仅仅是缺乏要处理的数据。我们无法让内存总线跑得更快,这就是为什么内存带宽往往是一个难以克服的硬性限制。
最后,如果所有选项都已穷尽,内存带宽仍然是限制因素,改善状况的唯一方法就是购买更好的硬件。您可以在具有更多内存通道的服务器上投入资金,或购买传输速度更快的 DRAM 模块。这可能是一个昂贵的选择,但仍然是加速应用程序的可行方案。