内存墙
这一阶梯上的每一篇指南,迄今都在讲如何让运算*更快*——更小的晶体管、FinFET 和 GAA 沟道、更多的核心、专用引擎。但一颗每秒能做一万亿次乘法的处理器,如果大部分时间都耗在*等待要相乘的数字*上,那它就毫无用处。几十年来,逻辑速度和内存速度的增长速率天差地别:处理器吞吐量陡然攀升,而主存能交付数据的速度却在爬行。两者之间的差距年复一年地拉大,这道越拉越大的鸿沟有个名字——内存墙。
看清两者*为何*分道扬镳很有帮助。逻辑一路紧贴 摩尔定律:塞得更多、切换更快,循环往复。而主存——DRAM——首要追求的是密度,以十亿计地堆出廉价的比特;从一个遥远的存储单元里读出一个比特、再把它跨过电路板运送过来,这套物理过程根本没能以同样的速度提速。于是芯片越来越饥饿,厨房却始终以同一个节奏上菜。结果就是处理器在大多数时间里处于*空闲*——不是因为没活儿干,而是因为它需要的数据还没送到。
重点是带宽,而不只是容量
这里有一个绊倒大多数人的区分。内存有两个截然不同的数字。容量是它能装*多少*——以 GB 计,相当于仓库的大小。带宽是你能*多快*地把数据搬进搬出——以 GB/秒计,相当于装卸月台的宽度。人们本能地担心容量(“我的模型是不是大到放不下?”),但在现代加速器上,一次又一次真正先用完的,其实是带宽。
一个厨房的比喻能把它说具体。容量是你储藏室的大小;带宽则是你每分钟能从储藏室往灶台搬多少食材。哪怕你拥有一仓库的食物,只要两者之间只有一道窄门,你照样做菜很慢。更糟的是,这个问题是可以量化的:假设你的处理器每做 1 次算术运算就需要 100 字节的数据,那么无论算术单元多快,那道门都决定了你的真实速度。工程师用运算密度来追踪它——即每取一个字节所完成的运算次数。当密度很低时,你就是*受内存限制(memory-bound)*的,此时换一个更快的运算引擎对你毫无帮助。
HBM:把 DRAM 堆起来
那么,要怎么把装卸月台加宽呢?一个简单粗暴的答案是:不再把内存芯片*平铺*在电路板上、靠一小撮窄窄的引脚去够它们,而是把它们垂直堆叠成一座高塔,再笔直地穿过硅打出连接。这就是 高带宽内存(HBM):把普通的 DRAM 裸片——通常 8 颗、12 颗甚至更多——一颗叠一颗地摞起来,键合成单独一个立方体。
奥妙在于垂直布线。堆叠中的每一颗裸片都被成千上万个 硅通孔(TSV)刺穿——那是一个个灌满铜的微小孔洞,*贯穿*硅,把一颗裸片直接连到它上方和下方的裸片。信号不必再跑到芯片边缘、横穿电路板、再绕回来,而是搭上一段短短的“电梯”,径直顺着这座塔向上。连接短,就意味着你能负担得起*非常多*的连接,而大量并行的连接正是带宽的本质所在:每一摞堆叠提供一条 1024 位宽的通路,相比之下传统内存只有 32 位或 64 位。
ordinary DRAM (flat, narrow bus) HBM stack (tall, very wide bus)
[DRAM] [DRAM] [DRAM] +----------+
| | | | DRAM 8 |
+------+------+ <- ~64-bit bus, +----------+
| long board traces | DRAM 7 | } each die
[ logic ] +----------+ pierced by
| ... | 1000s of
wide = few wires, far apart +----------+ TSVs (||||)
| DRAM 1 |
+----------+
| base die | <- 1024-bit bus
+----------+
|||| TSVs straight up中介层上的 HBM
一条 1024 位的总线很美妙,但它带来了一个新问题:上千根线得从内存立方体接进逻辑芯片,而普通封装根本没法把这么多精细的连接并排布出来。解决办法是把 HBM 堆叠和逻辑裸片*两者*都安放在一块共用的硅板上,这块板叫 中介层——本质上是一块微型、超致密的电路板,只不过它由硅制成,因而能承载像芯片本身一样精细的线。
由于中介层是硅做的,它能在内存和逻辑之间并排塞进成千上万根微观走线,两者仅相隔几毫米。HBM 堆叠最终就*紧挨着*处理器——不是隔着一块板,而是几乎贴在一起——由一条宽到用任何其它方式都布不出来的总线连接起来。这种布局是 异质集成 与 先进封装 的旗舰范例:内存和逻辑各自分开制造,各用自己最擅长的工艺,再在中介层上结合到一起。这和 芯粒 那篇指南里的理念如出一辙——在对的工艺上造出对的那一块,再缝合起来——只不过这次应用到了内存上。
short, very wide bus (1000s of wires)
+-----------+ <==============================> +-----------+
| HBM stack | | LOGIC |
| (DRAM x8 | | die (GPU/|
| + TSVs) | | AI accel)|
+-----------+ +-----------+
===|===========|=======================================|===========|===
| silicon INTERPOSER (fine wiring, both dies sit on it) |
===============================================================
| package substrate |
+--------------------------------------------------------------+
o o o o o o o o o o o <- solder balls to board近内存与存内计算
HBM 把装卸月台大幅加宽了——但请注意,它依旧是*同一个思路*:取来数据,把它运到运算引擎,再在那里做运算。每一个字节仍然要跑一趟来回,而搬动一个字节是要耗费能量和时间的。于是一个更激进的问题随之而来:如果我们不再把数据往运算这边拖,而是反过来,把一点点运算搬到数据那边呢?
这就是被称为近内存计算与存内计算的一类思路。*近内存*把简单的处理逻辑放到内存紧旁边——比如放在 HBM 堆叠下面那颗基底裸片上——这样归约和过滤就能在数据离开之前先完成。*存内*(即 compute-in-memory,存内计算)走得更远,直接在内存阵列*内部*完成运算:由于内存网格的连线方式,可以诱使一排存储单元几乎免费地做一次乘加,而这恰恰是 AI 最倚重的运算。其动机直截了当——如果连线才是瓶颈,那么最便宜的数据搬运,就是你压根不做的那一次。
AI 对带宽的饥渴
每一种工作负载都能感受到内存墙,但 AI 撞得最狠,值得弄清楚原因。训练和运行一个大型神经网络,其核心就是在做巨大数字矩阵的乘法——数以十亿计的权重。每个数字上的算术微不足道(一次乘法加一次加法),但你必须把*每一个权重*都流经运算引擎,而且往往每一批输入都得重来一遍。这正是前面讲过的低运算密度、受内存限制的情形,只不过被放大到了行星级的规模:模型大到根本无法待在快速的片上内存里,于是只能持续不断地从 HBM 中取出来。
这正是为什么我们将在最后一篇指南中遇到的那些 AI 加速器——GPU、TPU、NPU——都被一摞摞 HBM 包裹着,也是为什么每一代新芯片在吹嘘*内存带宽*时,嗓门跟吹嘘算力时一样大。一个面向 AI 的 领域专用架构,不只是一个更快的乘法器;它是一个由尽可能宽的管道喂养的更快乘法器,而且数据被精心布置,让这根管道永不断流。收束本阶梯的那篇压轴综述会把这些线索串到一起:专用化、封装与带宽,不是各自独立的把戏,而是同一套策略——当你再也无法把晶体管做得更好时,你就去把*整个系统*做得更好,而喂饱这头猛兽,正是这场仗的一半。