首页 › programming › 越快越小越贵:内存金字塔为何差上亿倍

越快越小越贵:内存金字塔为何差上亿倍

导语:你的代码慢,八成不是 CPU 的锅

打开任何一个性能剖析器,你会看到一个反直觉的真相:在现代程序里,CPU 真正在"算"的时间往往只占很小一部分,剩下的大把时间它都在发呆等数据。等谁?等内存。2026 年 5 月,专注"把硬件讲成人话"的频道 Branch Education 上传了一期 36 分钟的硬核科普《How does Computer Cache, Memory, and Storage Work?》,把这层从 CPU 寄存器一直堆到机械硬盘的"内存金字塔"用动画一层层拆开给你看。这期视频发布不到六周播放就突破 31 万,对一个深度技术长视频而言相当能打。

它解决的核心困惑是:为什么计算机不干脆全部用最快的内存? 答案藏在三个互相打架的目标里——快、大、便宜,你最多只能同时满足两个。于是工程师用一个跨度高达上亿倍速度差的金字塔结构,把"又快又大又便宜"这个不可能三角硬生生拼了出来。而作为程序员,理解这座金字塔,就是理解为什么数组比链表快、为什么矩阵按列遍历会慢十倍、为什么数据库要用 B 树——这些日常编程的"常识",本质上全都是缓存问题。本文带你把这座金字塔从底到顶拆透。

视频背景卡片

项目 内容
视频标题 How does Computer Cache, Memory, and Storage Work? 🖥️💿🛠️
频道 Branch Education
订阅数 272 万
时长 36 分 23 秒
播放量 31 万+(持续增长,截至 2026-07)
发布日期 2026-05-28
核心主题 内存层次结构(寄存器→缓存→内存→存储)与缓存工作机制

核心内容拆解

要点一:三个目标打架,逼出了金字塔

视频的开场就抛出了整个内存体系存在的根本原因:任何存储介质都在三个维度上被衡量——速度(延迟)、容量、价格(每比特成本)。问题是,物理定律不允许你全都要。SRAM(静态内存,做缓存用的)极快,但一个比特要 6 个晶体管,贵且占地方;DRAM(动态内存,做主存用的)一个比特只要 1 个晶体管加 1 个电容,便宜密度高,但慢一个量级还得不停"刷新";NAND 闪存(做固态硬盘)更便宜更密,但更慢;机械硬盘最便宜,慢到令人发指。

这是一个经典的工程不可能三角。延伸分析:视频强调的是"取舍"(trade-off),但更深的洞察是——既然没有任何一种介质能同时满足快、大、便宜,那就别逼某一种介质干所有活,而是把它们叠成层级。最顶上放一点点最贵最快的(寄存器、L1 缓存),中间放中等档(L2/L3、主存),底下堆海量便宜慢的(SSD、HDD)。统计数据显示,程序访问的数据有一个极强的规律:局部性(下一节细讲),所以绝大多数访问会被最顶上那一层挡住,金字塔平均下来就"又快又大又便宜"了。这是整个体系结构的灵魂。

要点二:上亿倍的速度跨度,一张延迟表说清

视频用一个不断缩放的动画展示了从 CPU 到远端网络的延迟谱。把这组数据单独拎出来,就是著名的"每个程序员都该背下来的延迟数字"(Latency Numbers Every Programmer Should Know,源自 Google 工程师 Jeff Dean):

操作 大约延迟 换算成"CPU 周期"
寄存器访问 ~0.3 ns 1 周期
L1 缓存命中 ~0.5–1 ns 3–4 周期
L2 缓存命中 ~7 ns ~14 周期
L3 缓存命中 ~20–40 ns ~40–80 周期
主存(DRAM)访问 ~100 ns ~200–300 周期
SSD 随机读 ~150 μs(15 万 ns) ~30 万周期
机械硬盘寻道 ~10 ms(1000 万 ns) ~2000 万周期
跨数据中心往返 ~150 ms ~3 亿周期

从最快的寄存器到最慢的跨大洋网络,速度差超过 5 亿倍;算上极端的远端存储,逼近十亿倍。视频原话的精髓在于那个"时间尺度换算"的比喻:如果把一次 L1 缓存命中比作 1 秒钟,那么一次主存访问大约要等 3 分钟,一次 SSD 读取要等半天,一次硬盘寻道要等几个月,而一次跨大洋网络请求要等好几年。CPU 就是在这样一个跨度惊人的"时间悬崖"上工作的——这也是为什么"缓存命中"和"缓存缺失"差一个字,性能却能差几百倍。

要点三:SRAM、DRAM、NAND 背后的物理代价

视频专门用动画对比了三种主流存储介质的物理结构,这一段极其精彩。SRAM(做缓存):一个比特由 6 个晶体管组成的双稳态触发器保存,读写极快(亚纳秒级),但密度低、功耗高、价格最贵,所以只能做得很小(L1 通常才几十 KB)。DRAM(做主存):一个比特由"一个晶体管 + 一个电容"保存,靠电容里的电荷存 0/1,密度高、便宜,所以能做几十上百 GB;代价是电容会漏电,必须每几十毫秒"刷新"一次(refresh),否则数据丢失,而且访问慢得多。NAND 闪存(做 SSD):靠浮栅晶体管锁住电荷,非易失(断电不丢),密度更高更便宜;代价是写入要先擦除、有擦写寿命(P/E cycles),且延迟是 DRAM 的一千倍以上。

延伸分析:这条介质链条告诉我们一件事——"快"和"便宜"在物理上根本是相反方向。SRAM 一个比特要 6 个元件,DRAM 只要 2 个,这就是为什么缓存做不大。这也是为什么"把所有数据放进最快缓存"在物理和经济上都不可能:一颗能装下 16GB 数据的全 SRAM 芯片,体积、功耗、成本都会爆炸。金字塔不是偷懒,是物理定律逼出来的唯一解。

要点四:64 字节的搬运单位——缓存行与局部性

这是整期视频对程序员最关键的一课。CPU 跟缓存、内存之间搬运数据,不是一个字节一个字节搬,而是一次搬一整块,这块叫缓存行(cache line / cache block),今天的主流大小是 64 字节。哪怕你只读一个 int(4 字节),硬件也会把这 4 字节所在的整条 64 字节缓存行一起搬进 L1。这个机制之所以有效,靠的是两条统计规律:

视频原话反复强调:"缓存不是随机给你的,它赌的就是你会继续用附近的数据。" 一旦你的访问模式打破了这两个赌注——比如在内存里乱跳着访问,或者遍历链表那样东一个西一个的节点——缓存行预搬进来的数据就白白浪费了,每次访问都变成昂贵的"缓存缺失"。这就是为什么同样的算法,常数因子能差出几十倍。

要点五:缺失一次代价三百周期——内存墙

把上面两节合起来,就撞上了计算机体系结构里大名鼎鼎的内存墙(memory wall)。CPU 速度在过去几十年按摩尔定律飙升,主频从几兆赫涨到几吉赫,但 DRAM 的访问延迟改善得极慢。结果就是:CPU 算一个加法只要不到 1 纳秒,但等一个没在缓存里的数据要 100 纳秒——中间那 99 纳秒 CPU 在干等,相当于空转两三百个周期。

视频提到,为了对抗这堵墙,硬件工程师堆了一整套把戏:①更深的缓存层级(L1/L2/L3,越往下越大越慢);②硬件预取(prefetch),prefetcher 会猜你接下来要访问哪块内存,提前把它搬进缓存;③乱序执行(out-of-order execution),CPU 遇到一条在等内存的指令,不会傻等,而是先去执行后面不依赖它的指令;④同步多线程(SMT/超线程),一个物理核跑两个线程,一个线程等内存时,另一个线程顶上,让执行单元别闲着。延伸判断:这些机制的本质都是"藏延迟"——既然内存拖后腿,就想办法让 CPU 在等待时不闲着。但对程序员而言,这些硬件把戏救不了一个访问模式烂到预取器都猜不中的程序。

要点六:多核的暗坑——缓存一致性与伪共享

视频后半段进入多核场景,这里埋着一个几乎所有并发程序员都踩过的坑。现代 CPU 每个核都有自己的私有 L1/L2 缓存,于是同一个内存地址可能同时存在于多个核的缓存里。如果核 A 改了自己缓存里的副本,核 B 看到的还是旧值——数据就不一致了。硬件用一套缓存一致性协议(最经典的是 MESI,四个状态 Modified/Exclusive/Shared/Invalid)来保证:任何一个核修改某缓存行,其他核里对应的副本会被标记为无效(invalidate),强制重新从内存或 A 核拿新值。

由此引出一个隐蔽的性能杀手:伪共享(false sharing)。假设两个线程分别更新两个不同的变量,看似互不干扰,但如果这两个变量恰好落在同一条 64 字节缓存行里,MESI 协议就会让这条缓存行在两个核之间来回弹(ping-pong)。每次写都让对方缓存失效,于是两个"独立"变量实际上在反复触发缓存同步,性能可能掉一个数量级。实战提示:这就是为什么写高性能并发代码要做"缓存行对齐"(比如 C++ 的 alignas(64),Java 的 @Contended),把热点变量独占一条缓存行,从根上避免伪共享。

要点七:金字塔的下半截——虚拟内存与换页

视频最后把视角拉远,连上硬盘,讲了虚拟内存(virtual memory)。操作系统给每个程序一个"假的"连续地址空间,背后用页表(page table)把这些虚拟地址映射到真实的物理内存,映射以"页"(通常 4KB)为单位。当程序访问的数据正好在物理内存里,皆大欢喜;一旦访问到还没映射进内存的页(比如被换出到硬盘了,或还没分配),就触发缺页中断(page fault),OS 得从 SSD/硬盘把这页搬进来——这一次"访问"可能要几百微秒到几毫秒,比正常内存访问慢上千倍。

为了加速地址翻译,CPU 里有个小缓存叫 TLB(Translation Lookaside Buffer),专门缓存最近的虚拟→物理地址映射。TLB 也是缓存,一样会缺失,一样有"局部性"红利。延伸分析:从这里能看出,金字塔根本不止 CPU 内那几层,它一路延伸到 SSD、HDD,甚至网络存储——越往下越慢越便宜,逻辑完全一致。所谓"换页(swap)",就是金字塔顶层数据紧张时,OS 自动把冷数据沉到底层硬盘,腾出快的内存给热数据。一旦你的程序触发的缺页太多,整个系统会陷入"抖动(thrashing)",疯狂在内存和硬盘间搬数据,性能直接崩盘。

知识结构图

flowchart TD
    A[内存金字塔的根本矛盾<br/>快 / 大 / 便宜 不可兼得] --> B[解决方案: 分层缓存]

    B --> C[第1层 CPU 寄存器<br/>~0.3ns / 几十字节]
    B --> D[第2层 L1 缓存 SRAM<br/>~1ns / 32-64KB]
    B --> E[第3层 L2/L3 缓存 SRAM<br/>~7-40ns / MB级]
    B --> F[第4层 主存 DRAM<br/>~100ns / GB级]
    B --> G[第5层 SSD NAND<br/>~150μs / TB级]
    B --> H[第6层 HDD / 网络<br/>~10ms+ / 无上限]

    D & E --> I[核心机制: 缓存行 64字节]
    I --> I1[空间局部性: 连续访问]
    I --> I2[时间局部性: 重复访问]
    I --> I3[命中 vs 缺失: 差几百倍]

    F --> J[内存墙: CPU干等数据]
    J --> J1[硬件预取]
    J --> J2[乱序执行]
    J --> J3[超线程]

    E --> K[多核: MESI缓存一致性]
    K --> K1[伪共享 false sharing]
    K --> K2[缓存行对齐]

    G --> L[虚拟内存: 页表 + TLB]
    L --> L1[缺页中断 ~ms级]
    L --> L2[换页与抖动]

    style C fill:#ffb3b3
    style D fill:#ffd699
    style F fill:#b3d9ff
    style G fill:#d9b3ff
    style H fill:#b3ffb3

实战启示:把"缓存直觉"刻进你的代码

这座金字塔不是 CPU 设计师的私事,它直接决定你写的代码快不快。下面几条是看完视频后能立刻用上的"缓存直觉":

第一,能用数组就别用链表。 链表的每个节点散落在堆里随机位置,遍历时每个节点都是一次缓存缺失;数组连续存放,64 字节缓存行一次搬进 16 个相邻元素,绝大多数访问都是命中。即便链表的插入是 O(1),由于缓存缺失的常数因子太大,实际工程里数组 + 倍增扩容几乎总是更快。这就是为什么现代语言的默认列表(Python list、Go slice、C++ vector)底层都是连续数组。

第二,警惕遍历方向的陷阱。 C/C++、Java、NumPy 这些语言/库的二维数组默认是行主序(row-major)存储。按行遍历是连续访问,飞快;按列遍历每次都跨一整行跳到下一条缓存行,全是缺失,能慢十倍。当你发现一段矩阵代码莫名地慢,第一个该查的就是遍历顺序。

第三,AoS 改 SoA 能救命。 处理大量实体时,"结构体数组(AoS)"会把每个实体的所有字段打包在一起,但你往往只批量处理其中一个字段(比如更新所有实体的位置),于是缓存行里塞满了此刻用不到的字段。改成"数组结构(SoA)"——把所有实体的位置单独存成一个连续数组——就能让缓存行全是你要的数据。游戏引擎的 ECS 架构、SIMD 向量化、数据库列存,本质都是这个道理。

第四,数据库用 B 树而不是二叉树,纯粹是缓存问题。 二叉树每个节点存一个值、两个指针,查一个值要访问很多节点,每个节点都可能缓存缺失。B 树把节点做大到正好填满一条缓存行甚至一个磁盘页,每访问一个节点就能筛掉大量数据,让树高变矮、缓存缺失变少。这是"为存储层次量身设计数据结构"的教科书案例。

第五,连 AI 推理都被这堵墙卡住。 今天大模型推理的瓶颈往往不是算力,而是显存带宽——权重和 KV cache 太大,搬运它们比计算它们慢得多。量化(把 FP16 压成 INT8/INT4)、KV cache 压缩、Flash Attention 这些热门技术,本质都是在对抗"把数据搬进计算单元"的延迟。内存墙在 AI 时代换了张脸又回来了。

一句话总结这条启示:优秀的程序员写的是"缓存友好"的代码——不是算法复杂度最优就够了,还要让数据访问模式顺着 64 字节缓存行和局部性规律走。很多时候,把常数因子优化好,比换一个更优的算法还管用。

延伸学习路径

  1. 《每个程序员都该知道的延迟数字》(Jeff Dean 原版 + 互动可视化 evity.github.io)——把本文那张延迟表玩出肌肉记忆。
  2. Gustafson 的 Memory Hierarchy & Cache 友好编程系列( Utah 大学课程讲义公开版)——系统讲 cache-oblivious 算法、分块/tiling。
  3. 《Computer Organization and Design》(Patterson & Hennessy)——内存层次与缓存一致性的权威教材,第 5 章起。
  4. Brendan Gregg 的 Systems Performance 性能分析方法论——实战剖析缓存缺失、TLB、伪共享的真实案例。
  5. Branch Education 同频道《How do CPUs Work?》与《The Sections inside a CPU》——作为本期视频的前置和互补,从晶体管一路讲到流水线,动画一流。

一句话总结

内存金字塔用一层层"又快又小又贵"叠在"又慢又大又便宜"之上,硬是把一个上亿倍速度差的物理不可能三角,凑成了今天又快又大的计算机——而你看懂了它,就拿到了写出高性能代码最关键的那把钥匙。

参考来源

  1. How does Computer Cache, Memory, and Storage Work? — Branch Education — 本文分析的核心视频
  2. Latency Numbers Every Programmer Should Know(Jeff Dean 经典版) — 延迟数字表原始来源
  3. Computer Organization and Design — Patterson & Hennessy — 内存层次权威教材
  4. False Sharing in Multithreaded Programs — Dr. Dobbs / Intel — 伪共享与缓存行对齐实战
  5. The Memory Wall: Past, Present, Future — McKee et al. — 内存墙的学术综述

本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入