从缓存到HBM,一文讲清内存为什么成了现代计算的瓶颈

来源:半导纵横发布时间:2026-08-21 10:47
算力
存储
生成海报
算力与内存的鸿沟越拉越大。

数十年来,计算性能总能被简化为几个醒目的规格参数。CPU靠主频和核心数售卖,GPU靠着色器吞吐量以及后来的teraFLOPS,内存看频率,存储看顺序传输速率。这些数字至今仍有参考价值,但现代处理器的算术能力已经强大到另一个问题日益决定着理论性能中究竟有多少能被真正利用:让数据在需要的时间到达需要的位置。

一颗现代CPU核心每个时钟周期可以执行多条指令。高端GPU包含数千个并行运算单元。AI加速器将矩阵乘法吞吐量推进到petaFLOP级别。然而,如果没有操作数、指令、纹理、几何数据、模型权重、中间结果或其他形式的数据,这些单元中没有任何一个能算出有意义的结果。

这造成了一种根本性的失衡。事实上,这些年来算术吞吐量的提升幅度极为惊人,但在延迟、带宽、能耗和芯片物理资源方面,搬运数据的成本相对要昂贵得多。其结果是,许多现代工作负载将大量精力耗费在喂饱执行单元这件事上。

这并不意味着每种工作负载都是“内存受限”的。远非如此。性能仍然可能受制于计算吞吐量、指令依赖、分支预测、同步、软件开销、存储、网络或众多其他因素。真正改变的是,理解内存行为已经成为理解现代计算性能不可或缺的一环。

而“内存性能”本身远不止频率或容量。延迟、带宽、局部性、缓存容量、内存级并行度、访问模式、预取、容量、互连拓扑,甚至数据物理上驻留的位置,所有这些因素都在相互作用。

要理解其中缘由,必须从最重要的一个区分开始:数据是如何被访问的。

区分顺序访问与随机访问

想象从头到尾读取一个1 GB的文件。下一个数据块的位置是完全可预测的。系统一旦识别出你的行为模式,就可以在数据被显式请求之前开始预取后续数据。

这是顺序访问模式,现代计算机极其擅长处理它。CPU内置专门识别可预测内存流的硬件预取器。DRAM控制器可以保持多个事务在途并重排请求。SSD控制器将访问分散到大量NAND晶粒和通道。GPU可以将相邻线程的内存请求合并为更大的事务。

硬件本质上可以构建一条流水线。遗憾的是,随机访问是一道更难跨越的障碍。

考虑遍历一个链表,每个节点包含下一个节点的地址。在当前访问完成之前,处理器可能根本不知道下一个访问将去往何处。这摧毁了大部分预取机会,也使机器无法高效地重叠访问。这就是为什么两种工作负载搬运的数据量相同,运行速度却可能天差地别。

当涉及延迟依赖时,这一区分变得更加重要。如果CPU请求四条互不相关的缓存行,它可能同时保持多个缓存未命中在途,重叠大部分延迟。但如果请求B依赖于请求A的结果,那么B在A完成之前甚至无法开始。

指针追踪(pointer chasing)是最常见的例证。每次加载揭示了下一次加载的地址,迫使处理器承担大部分真实的内存延迟,而非通过推测或并行来隐藏它。

同样的原则在计算领域无处不在。执行小型不可预测查找的数据库与复制大文件面临着截然不同的挑战。GPU采样相邻一致纹素的行为,与数千个线程追逐无关地址的行为大相径庭。SSD顺序读取数百KB数据与检索分散的4 KB块,本质上是两种工作负载。

这也解释了为什么我们不能简单地“将随机访问转化为顺序访问”来提升性能。尽管如此,软件开发人员确实在尝试这样做。数据库重组数据,游戏引擎批处理任务,GPU算法重排请求,编译器改变数据布局。结构体数组(SoA)有时可以替代数组结构体(AoS)。排序可能将分散的访问转化为相对一致的访问。

但这样做并非总能实现。事实上,如果下一个地址依赖于当前操作的结果,那么这种依赖是真实的。如果一条光线可能弹射向3D场景中不可预测的区域,GPU就无法预知每一次后续访问。如果数据库用户请求一条特定记录,先读取1 TB的相邻记录显然违背初衷。

因此,目标与其说是消除随机访问,不如说是让昂贵的访问尽可能少发生、尽可能可预测、尽可能并发地发生。

顺序访问按顺序读取相邻数据,从而实现高效的预取和高吞吐量。随机访问则在不相关的位置之间跳跃,增加了预测难度并导致更高的延迟。

局部性是缓存层次结构有效的原因

真实软件很少始终访问完全任意的数据。实际上,程序通常同时表现出空间局部性和时间局部性。

空间局部性意味着,如果程序访问了某一数据,它在不久后需要相邻数据的概率相对较高。时间局部性意味着,最近访问过的数据有合理的概率被再次访问。处理数组的循环具有出色的空间局部性。频繁引用的游戏世界数据可能具有很强的时间局部性。热循环——一段被极其频繁执行的代码——中的指令同时表现出两种局部性。正是这些特性使缓存成为可行方案。

当CPU需要DRAM中的一个字节时,它通常不会只传输那一个字节。数据以固定大小的块——缓存行——在缓存层次结构中移动。主流x86 CPU的缓存行通常为64字节。例如,AMD自身的优化文档就描述了围绕64字节缓存行的软件布置和访问考量。

如果程序随后访问相邻数据,它们可能已经位于缓存中。这引入了另一个关键概念:工作集。

一个程序在技术上可能分配了数十GB内存,但在某个特定阶段只反复操作其中一小部分。如果这个活跃工作集能放入快速缓存,性能可以非常出色。工作集稍微超出可用缓存容量,突然就会有多得多的访问溢入更慢的层次。这可能产生惊人的性能突变。

这也是为什么缓存容量提升有时带来巨大收益,有时几乎毫无效果。将缓存从32 MB增加到96 MB,如果能让一个60 MB的频繁复用工作集留在片上,价值极大;但如果工作负载只是顺序流经数GB且不再复用的数据,收益就要小得多。

因此,只有当软件给缓存值得记住的东西时,缓存才能发挥最大效用。

空间局部性指的是在短时间内连续访问相邻的内存位置,而时间局部性指的是在短时间内重复使用相同的数据。这两种特性都使得缓存能够处理更多请求,而无需反复访问速度慢得多的主内存。

为什么CPU有多级缓存而非一个巨大缓存

这引出了一个显而易见的问题。既然缓存如此有用,为什么不直接构建一个超大型超快缓存,淘汰慢速内存?因为我们期望内存具备的特性彼此冲突。

最靠近CPU的缓存由SRAM构成,针对极低访问延迟和极高带宽优化。但SRAM消耗大量硅片面积。更大的结构还需要更多布线、更长的物理路径、更复杂的查找逻辑,且访问时通常消耗更多能量。

随着容量增加,维持微型本地缓存的速度变得越来越困难,这正是层次结构存在的主要原因。

L1缓存足够小,可以紧贴执行核心,以极低延迟提供数据。L2提供更大容量,延迟稍高。最后一级缓存(现代CPU通常为L3)提供更大容量,可能在核心间共享,但访问速度通常更慢。所有层级都未命中时,请求最终必须前往慢得多的DRAM。

缓存设计远不止容量这一维度。相联度影响数据块可放置的位置,可以减少冲突未命中,但更高的查找灵活性增加了复杂度。缓存分区(cache banking)可以提升并行访问能力。多端口提高吞吐量但消耗面积和功耗。私有缓存为各核心提供快速本地访问,而共享缓存可以更高效地利用总容量并简化某些形式的数据共享。

英特尔在其架构研究中讨论过这一精确的设计张力,将缓存组织描述为容量、相联度、延迟、带宽、私有与共享组织方式、可扩展性和能效之间的平衡行为。

此外还有一致性问题。当多个CPU核心缓存了同一内存的副本时,系统必须确保它们不会无限期地基于相互矛盾的数据版本运行。维护这种一致性视图会产生额外的通信和簿记开销,在核心数增加时尤为明显。因此,更大的缓存并非普适的免费午餐。

AMD的3D V-Cache技术是工程师在这一权衡中找到另一条出路的现代范例。AMD没有在水平方向大幅扩展CPU核心裸片,而是垂直堆叠额外的缓存裸片。其第二代实现采用直接铜—铜键合和硅通孔(TSV),增加了一颗64 MB L3缓存裸片。

Ryzen X3D处理器在游戏中的受欢迎程度,提供了额外缓存与工作负载相匹配时实际效果的生动演示。游戏不断操作世界状态、绘制调用数据、物理结构、动画、可见性信息以及众多其他数据结构。将更多频繁复用的信息保持在CPU附近,可以减少昂贵的DRAM访问。

但即使在游戏中,不同游戏间的收益差异也相当大。有些游戏的关键数据已经能放入常规/较小缓存;有些在其他方面受限;有些则收益巨大。

这种差异性恰恰是缓存层次理论所预测的。

CPU 缓存按层级排列,以平衡速度和容量:L1 最小、速度最快,L2 容量更大、延迟稍高,而 L3 通常是最大、速度最慢的缓存级别,并且通常由多个 CPU 核心共享。

DRAM性能远不止频率和CAS延迟

最终,缓存中没有的数据必须从主存(即DRAM)获取。DRAM以远低于SRAM的每比特成本提供大得多的容量,但速度也慢得多。因此工程师用带宽和并行度来补偿。

现代DRAM内部分为bank和bank group。bank内是存储单元行。访问数据通常需要先将一行激活到行缓冲区中,然后再读取或写入目标列。这导致三种简化场景:如果所需行已经处于激活状态,控制器获得行缓冲区命中;如果没有相关行打开,必须激活一行;如果bank当前打开了错误的行,可能需要先关闭现有行再激活新行。

因此,内存控制器所做的远不止盲目转发CPU请求。它追踪在途事务,尝试在通道、rank、bank group和bank之间高效调度,同时遵守大量内存时序约束。这正是内存带宽和内存延迟不应被混为一谈的原因之一。

延迟描述单次操作需要多长时间,带宽描述单位时间内能传输多少数据。一个系统可以拥有巨大的聚合带宽,却在处理一连串依赖型随机内存访问时表现糟糕。相反,一个能够保持数百个独立事务在途的工作负载,可以容忍较大延迟,同时仍接近可观的总体吞吐量。

DDR5内存体现了现代内存设计对并行度的强烈依赖。与DDR4相比,DDR5增加了bank group数量,将默认突发长度从8翻倍至16,并将一条DIMM划分为两个独立子通道。美光特别指出,增加bank group提高了使用限制更宽松的bank group时序的概率,并允许更多内存页同时保持打开状态。

这也解释了为什么DRAM调优有时会产生令人沮丧的不一致结果。提高传输速率提升了理论带宽,收紧时序可以减少各种延迟,增加rank可能影响可用并行度。而内存控制器、CPU架构和应用行为共同决定了任何改进中有多少能真正传递到软件。

因此,压缩基准测试、游戏、数据库和大文件复制对同一次内存升级的反应可能截然不同。

GDDR和HBM解决同一问题的不同版本

GPU需要巨大的带宽,因为数千条执行通道可能并发请求数据。消费级GPU因此使用GDDR内存,通过相对较宽的接口连接,并以极高传输速率运行。

AI和HPC加速器则通过高带宽内存(HBM)将这一方向推得更远。HBM不是将内存封装放在处理器周围、通过传统板级接口驱动,而是将DRAM裸片堆叠,通过先进封装以极宽的接口紧贴计算器件放置。其结果是超凡的带宽和每传输比特良好的能效,代价是封装复杂度和成本的大幅提升。

AMD Instinct MI355X提供了当今规模的一个有用参照。单颗加速器搭载288 GB HBM3E,理论内存带宽最高达8 TB/s。八GPU系统因此包含2.3 TB HBM。这些数字对桌面CPU来说荒谬地过剩。但对现代AI而言,喂饱计算硬件已成为核心架构问题之一。

GDDR 和 HBM 内存分别应对现代 GPU 和加速器的不同挑战:GDDR 优先考虑消费级图形的高带宽、容量和成本效益,而 HBM 则优先考虑通过将堆叠内存放置在靠近处理器的位置来实现极高的带宽和能源效率,但代价是封装的复杂性和成本更高。

AI已将数据搬运变为一等性能问题

现代生成式人工智能——主要以大语言模型(LLM)的形式——或许最清楚地说明了为什么原始算术吞吐量只能讲述部分故事。大型神经网络涉及海量矩阵运算,这正是现代GPU和专用AI加速器被构建来执行的。但处理器仍必须先取出模型权重、激活值和中间数据,这些算术单元才能进行有用的工作。

训练对内存的需求尤其密集,因为系统需要维护的远不止模型权重。根据训练技术和优化器的不同,还可能需要梯度、优化器状态、为反向传播保留的激活值以及临时工作空间。

推理减少了其中一些需求,但产生了自身的内存挑战。

以一个70亿参数的大语言模型为例。在16位精度下,仅权重就需要约14 GB,这还不包括KV缓存和运行时开销。

量化有帮助,因为将每个参数从16位降至8位或4位可以减少存储和搬运模型所需的内存量。这就是低精度格式改善的不仅仅是存储容量的原因。当内存流量是瓶颈时,从内存中传输更少字节可以直接提升性能。

更广泛的启示远不止于AI。重计算和数据搬运通常是可互换的成本。有时存储结果比重新计算更便宜;有时从远处内存中取回一个值比重新计算更昂贵。现代架构越来越倾向于判断这种权衡中哪一方胜出。

像 ChatGPT 和 Claude 这样的基于 LLM 的现代聊天机器人依赖于庞大的模型,这些模型不断地在 GPU 内存中移动权重、激活值和缓存数据,因此内存带宽、容量和数据局部性对于快速高效的推理至关重要。

游戏是最复杂的内存工作负载之一

游戏尤其有趣,因为不存在单一的“游戏工作负载”。某一时刻CPU可能在遍历可见性/剔除结构并准备绘制调用,另一个线程可能在更新物理或AI。GPU同时处理几何数据、采样纹理、读取材质数据、写入渲染目标、执行着色器并访问加速结构。在开放世界游戏中,资源还可能在后台从存储流式传输到系统内存和VRAM。其中一些操作高度一致,另一些则不然。这有助于解释若干硬件趋势。

在CPU端,AMD的X3D处理器使用大容量最后一级缓存来捕获更多游戏使用的工作集。当关键游戏数据原本需要反复前往DRAM时,收益可能非常可观。

在GPU端,大容量最后一级缓存同样减少外部VRAM流量,提升有效内存带宽并大幅降低关键数据的访问延迟。NVIDIA、AMD和英特尔在各代GPU中都大幅调整了缓存结构,因为避免片外事务可以提升有效内存性能,而无需同等幅度地增加物理内存带宽。

实时光线追踪使数据行为更加困难。光线需要遍历层次包围盒(BVH)——一种树状数据结构,用于确定它们可能与哪些场景几何相交。与传统光栅化工作负载不同,光线可能发散并弹射向场景中完全不同的区域。

NVIDIA将此描述为执行和数据双重发散:相邻GPU线程可能遵循不同代码路径,同时访问难以合并或缓存的内存地址。其着色器执行重排序(SER)技术部分正是为了以改善执行和数据局部性的方式重组光线追踪工作。

这是一个重要案例,因为它表明更快的内存并不总是解决内存问题的唯一方案——有时更好的选择是重组工作,使现有内存子系统能被更高效地利用。

游戏还可能受限于容量而非带宽或延迟。如果所需纹理、几何和渲染资源超出VRAM容量,系统可能需要通过PCI-Express总线从系统内存搬运资源,或执行逐出和重载。一个拥有巨大理论带宽的GPU无法补偿数据根本不驻留在本地内存中的问题。

因此,即使在一帧之内,内存性能也有多个维度:多少数据能本地驻留、访问速度多快、访问合并的效率如何、缓存捕获复用的能力如何,以及架构能维持多少并行流量。

现代游戏中的实时光线追踪是一种高度不规则的工作负载,光线可能会发散到场景的不同部分,并触发对几何体、材质、纹理和BVH数据的分散访问,这使得高效的缓存和内存访问比许多传统的栅格化工作负载更加困难。

顺序带宽无法描述真实存储性能

存储或许最容易证明单一带宽数字可能具有多大误导性。现代PCIe NVMe SSD标称惊人的顺序吞吐量,但顺序传输代表的是一种极为有利的工作负载。大量连续请求允许控制器在NAND通道、晶粒和plane间高效分配工作,同时保持大量操作在途。然而真实应用频繁请求的是截然不同的东西。

操作系统、游戏、数据库和应用程序可能请求数千个相对较小、分散在驱动器各处的数据片段。这就是为什么SSD规格要区分顺序吞吐量与随机IOPS、队列深度和延迟。

Solidigm的工作负载文档将顺序访问定义为相邻块,随机访问定义为分散在介质上的块,队列深度定义为未完成I/O请求的数量。关键在于,增加队列深度可以通过暴露更多并行工作来提升吞吐量,但代价是延迟。这在概念上与DRAM非常相似。基于NAND闪存的SSD包含大量在控制器背后并行操作的闪存晶粒。NAND本身以页和更大的擦除块组织,写入不能像在DRAM中覆写字节那样处理。控制器执行地址转换、磨损均衡、垃圾回收和其他后台操作,使NAND看起来像一个普通块设备。

这些过程可能产生额外的内部流量,即写入放大——SSD物理写入的数据量超过主机请求的数据量。在持续工作负载下,垃圾回收还可能产生延迟尖峰。

消费级SSD通常通过快速写入缓存增加另一层层次结构。一部分NAND可能临时以类SLC模式运行,快速接受写入,之后数据再被折叠到密度更高的TLC或QLC存储中。一些驱动器还包含DRAM用于映射数据,而无DRAM设计可以使用主机内存缓冲区(HMB)等技术将部分映射结构保留在系统内存中。

存储设备同样有效地构建了自己的内存层次结构。一旦快速缓存耗尽,持续写入性能可能与产品页上展示的短暂基准测试突发速度截然不同。现代 PCIe NVMe SSD 的顺序读写速度可能非常快,但实际性能也很大程度上取决于随机 I/O、访问延迟、队列深度以及控制器处理大量分散的小请求的效率。

相同硬件可能快也可能慢

内存基准测试需要上下文应该已经很清楚了。

大文件复制需要持续的顺序带宽;对延迟敏感的数据库可能更关注小型随机访问和尾延迟;在密集数组上运行的科学仿真可以极好地利用流式带宽和向量化;编译器可能花费大量时间追踪空间和/或时间局部性较差的复杂数据结构;CPU受限的游戏如果热工作集能放入更大的最后一级缓存,可能获益巨大,而另一个游戏可能几乎毫无反应;AI训练同时需要巨大的计算吞吐量、容量和带宽。低并发LLM解码可能更依赖内存带宽。长上下文推理增加了KV缓存,将可用内存容量变成另一个核心资源。

甚至“带宽”这个词也需要限定。有理论接口带宽、持续应用带宽、缓存带宽、DRAM带宽、存储带宽和互连带宽。一种工作负载可能使其中一项饱和,却几乎不触及另一项。最终决定性能的,是应用的数据访问模式如何与整个层次结构交互。

现代计算越来越关注少搬数据,而不仅仅是搬得更快,这就是为什么现代处理器中一些最有趣的改进并非来自更快的算术单元。

缓存将复用数据保持在执行资源附近,预取器预测未来访问,内存控制器重排请求以暴露DRAM并行度,GPU线程调度尝试改善一致性,分块(tiling)将大问题划分为能放入较小内存的工作集,压缩减少必须传输的字节数,量化对AI模型做同样的事,HBM通过极宽接口将大量内存物理上移近加速器,3D堆叠在不强制每比特内存都放在同一平面裸片上的情况下增加容量,chiplet允许设计者更灵活地组合专用计算、缓存和I/O结构,而日益复杂的互连则试图防止CPU、GPU和加速器之间的通信成为下一道墙。

共同的主题很简单:尽可能高效地使用昂贵的数据搬运。原始计算性能将持续提升。内存带宽也会提升,缓存会增大,HBM会更快,SSD会进一步推进到每秒数十GB,先进封装将此前分离的组件拉得更近。然而,物理距离、能耗、容量和延迟决定了没有任何单一内存技术能够同时提供巨大容量、巨大带宽、可忽略延迟和可忽略成本。

因此,内存层次结构不会消失,而且它正变得更深、更精密。现代性能越来越取决于在处理器请求之前将正确数据放在层次结构的正确层级,以及组织软件使相同数据能被复用而非重新搬运。

一颗CPU核心等待依赖型内存访问耗费数百个时钟周期不是有用的计算。一个GPU的数千个算术单元空等VRAM不是有用的计算。一个AI加速器具备petaFLOPS能力却因模型数据供给不足而饿肚子不是有用的计算。如果应用程序无法高效发出和处理所需请求,一个14 GB/s的SSD同样不是有用的计算。

毕竟,最快的操作往往不是更快地取回数据,而是根本不需要取回。

本文转自媒体报道或网络平台,系作者个人立场或观点。我方转载仅为分享,不代表我方赞成或认同。若来源标注错误或侵犯了您的合法权益,请及时联系客服,我们作为中立的平台服务者将及时更正、删除或依法处理。

评论
暂无用户评论