如果你写过程序,你一定学过 Big-O 复杂度分析:O(1) 比 O(log n) 快,O(n log n) 比 O(n²) 高效。这套理论干净、优雅,几乎成了工程师衡量代码好坏的直觉。但 Branch Education 刚在 2026 年 6 月 23 日发布的这支长视频——《How does Computer Cache, Memory, and Storage Work?》——会把你这套直觉打翻在地。
它要讲的真相是:在现代计算机里,CPU 根本不在"算",而是在"等"。你的处理器主频是几个 GHz,一个时钟周期不到 0.3 纳秒,可去主存(DRAM)取一次数据却要 80~100 纳秒——慢了二三百倍;去硬盘取数据,更是慢到几毫秒,差出一千万倍。从寄存器到机械硬盘,整条存储阶梯的速度跨度接近十亿倍。这意味着:决定你程序快慢的,常常不是你做了多少次运算,而是你搬了多少数据、数据离 CPU 有多近。
这就是业界说的"内存墙(memory wall)"。视频用 Branch Education 一贯的高制作水准,把寄存器、L1/L2/L3 缓存、内存、SSD、硬盘这条阶梯拆给你看。本文我会把视频的核心讲透,并补上它没时间细说的工程推论——为什么 Big-O 在现实里经常"骗"你,以及怎么写真正快的代码。
| 项目 | 内容 |
|---|---|
| 视频标题 | How does Computer Cache, Memory, and Storage Work? 🖥️💿🛠️ |
| 频道 | Branch Education |
| 时长 | 长视频深度讲解(Branch Education 标志性的 20 分钟+ 长片格式) |
| 播放量 | 约 30 万(发布于 2026-06-23,24 小时内,且仍在快速增长) |
| 核心主题 | 计算机存储层级(registers→cache→memory→storage)与"内存墙" |
说明:本文分析基于视频公开信息(标题、频道、发布时间、播放数据经 dislike API 与频道 RSS 交叉核实)。因 IP 限制无法抓取字幕,技术细节由笔者结合计算机体系结构常识补充并明确标注。
视频反复强调的第一组反直觉数字,是 CPU 与主存之间的速度鸿沟。现代 CPU 一个时钟周期约 0.25~0.3 纳秒,而访问一次 DRAM 主存要 80~100 纳秒——CPU 在干等数据时,理论上能再执行 二三百条 指令。
打个 Branch Education 式的比方(这也是业界流传的经典比喻):如果把读寄存器比作"伸手拿桌上的笔",那么读 L1 缓存是"从抽屉里拿",读 L2 是"起身走到书架",读主存是"下楼去取",读 SSD 是"开车去一趟超市",而读机械硬盘,相当于"坐飞机飞到另一个国家取一趟"。速度差距不是 2 倍、3 倍,而是横跨了好几个数量级。
这条鸿沟有个学名:内存墙(memory wall),也叫 von Neumann 瓶颈。上世纪八九十年代,CPU 主频每 18 个月翻番,可 DRAM 速度的提升却慢得多,两者的剪刀差越拉越大。今天 CPU 已经快到"没数据可算"的地步——研究表明,大量通用程序里,CPU 的执行单元真正在全速运转的时间,往往只占 两三成,剩下七八成都在"内存停顿(memory stall)",干等数据从远处搬过来。
笔者延伸:这正是为什么 Apple 的 M 系列、各家"AI 芯片"拼命往芯片里塞内存带宽(HBM、宽内存总线)——因为算力早就过剩,瓶颈全在喂不饱的"数据食堂"。
视频把计算机的存储做成一张金字塔。从顶到底,越往上越快、越小、越贵;越往下越慢、越大、越便宜:
| 层级 | 典型容量 | 典型延迟(数量级) | 比喻 |
|---|---|---|---|
| 寄存器 register | 几十字节 | ~0.3 ns | 桌上的笔 |
| L1 缓存 | 几十 KB | ~1 ns | 抽屉 |
| L2 缓存 | 几百 KB~1 MB | ~3–4 ns | 书架 |
| L3 缓存 | 几十 MB | ~10–20 ns | 同一间房 |
| DRAM 主存 | 几~几十 GB | ~80–100 ns | 楼下 |
| SSD 固态硬盘 | 几百 GB~几 TB | ~10–100 μs | 开车去超市 |
| HDD 机械硬盘 | 几 TB | ~5–10 ms | 飞到另一个国家 |
这张表是整个体系的"宪法"。容量和延迟的反向关系,是一切优化策略的物理根源:因为快的东西天然又小又贵,所以工程师被迫设计出"分级"的结构——把最常用的少量数据放在最快的层,其余下沉到慢但大的层。问题就变成:怎么知道哪些数据该往上搬、哪些该往下沉? 这引出了缓存得以成立的唯一理由。
这是视频里最该被记住的一点:缓存这么小,凭什么能命中? L1 通常只有几十 KB,可你的程序动辄操作几 GB 数据。一个比数据小一万倍的缓存,竟然能挡住 九成以上 的访问——这在数学上几乎不可能,除非现实程序有一个隐藏的规律。
这个规律叫 局部性原理(principle of locality),分两种:
正因如此,设计者赌了一个朴素的"二八定律":程序 90% 的时间花在 10% 的代码/数据上。只要把这 10% 的"工作集(working set)"放进缓存,命中率达到 95% 并不稀奇。这是 MIT 的 Peter Denning 在 1968 年提出的"工作集理论"的核心洞察——缓存能work,不是因为硬件多聪明,而是因为人类写的程序天然"成块"地用数据。
笔者延伸:反过来想,如果你的代码故意"反局部性"——比如随机跳着读、把本该连续的数据散得到处都是——缓存命中率会瞬间崩塌,你的程序会"掉回"主存甚至硬盘的速度,慢上几十上百倍。缓存不是福利,是靠你的代码配合才拿得到。
视频会告诉你一个容易被忽略的事实:CPU 从不"读一个字节",它一次至少读一条缓存行(cache line),通常 64 字节。这意味着,当你访问数组里的第 0 个元素,CPU 实际上把第 0~63 字节全搬进了 L1。如果你下一行代码正好用到第 1 个元素——它已经在缓存里了,零额外成本。
这套机制催生了 硬件预取器(prefetcher):CPU 检测到你正在按地址顺序读,就"猜"你接下来还要继续往下读,提前把后面的缓存行搬进缓存。等你真要用时,数据已经就位。顺序访问之所以飞快,正是因为预取器配合空间局部性打出了"全场命中"。
笔者延伸:这也是为什么 C/C++ 里
struct的字段排列顺序会显著影响性能——把常用字段挤进同一条 64 字节缓存行,一次搬进来就够用;反之则要反复访问主存。这也是"伪共享(false sharing)"的根源:两个线程各改一个无关变量,只要它们恰好落在同一条缓存行里,硬件为了保证一致性,就会在两个 CPU 核之间反复"踢"这条缓存行,导致多线程程序反而比单线程还慢。
这是本文最想给你砸实的一个结论,也是视频内容的自然延伸(视频本身聚焦硬件原理,这里我帮你补上对软件的推论)。
复杂度分析只数"运算次数",却假设每次运算、每次内存访问成本一样。可在真实机器上,访问成本天差地别。于是经常出现这种"反常":
所以一句更贴近现实的话是:不要只优化运算次数,要优化"数据布局"和"访问模式"。让数据连续、让访问顺序、让热点紧凑——这三件事的价值,常常超过把算法复杂度从 O(n log n) 压到 O(n)。
为了让"等数据"的时间不那么致命,现代 CPU 内置了一整套你平时感觉不到的机制,视频会逐一介绍:
笔者延伸:这套"看不见的加速器"有个共同前提——它们都偏爱可预测、连续、局部的访问。你的代码越"规整",它们发挥得越好;你的代码越"跳跃",它们越帮不上忙。换句话说,高性能编程的本质,是顺着硬件的脾气写,而不是跟它对着干。
理论落到地面,几个经典案例最能说明问题:
这些案例的共同教训是:"内存墙"不是理论,它每天都在决定你打开 App 的速度、游戏的帧率、AI 推理的延迟。
flowchart TD
A["内存墙 Memory Wall<br/>CPU 几个 GHz,内存慢二三百倍"] --> B["根源:存储金字塔<br/>容量↑ 延迟↑ 价格↓"]
B --> C1["寄存器 ~0.3ns / 几十字节"]
B --> C2["L1/L2/L3 缓存 ~1–20ns"]
B --> C3["DRAM 主存 ~100ns"]
B --> C4["SSD ~10–100μs"]
B --> C5["HDD ~5–10ms"]
A --> D["缓存为何能命中?"]
D --> E1["时间局部性<br/>刚用的马上还用"]
D --> E2["空间局部性<br/>相邻的一起用"]
D --> E3["工作集理论 Denning 1968<br/>90% 时间花在 10% 数据上"]
E2 --> F["64 字节缓存行 + 预取器<br/>顺序访问一路命中"]
F --> G["工程推论:Big-O 在骗你"]
G --> H1["连续数组 O(n) 碾压<br/>指针跳转的树 O(log n)"]
G --> H2["数据导向设计 DOD<br/>按列重排提升命中率"]
G --> H3["结构体字段排布 / 伪共享<br/>影响多核性能"]
H1 --> I["本质:高性能编程 =<br/>顺着硬件脾气写代码"]
style A fill:#fde2e2,stroke:#c0392b,stroke-width:2px
style G fill:#fff3cd,stroke:#b8860b,stroke-width:2px
style I fill:#d4edda,stroke:#1e7e34,stroke-width:2px
读完这支视频,作为开发者你能立刻带走几条可落地的原则:
第一,把"数据布局"当成头等公民。 选数组而非链表、把 struct 里高频字段排在一起、用"结构体数组(SoA)"替代"数组结构体(AoS)"处理大批量数据。这些改动不增加复杂度,却能让缓存命中率从 50% 飙到 95%,速度差出一个数量级。
第二,警惕指针跳跃。 哈希表、链表、树、对象图里的引用,每一次"跳"都可能是一次缓存未命中。当你追求极致性能时,问自己一句:"这次访问能不能换成顺序的?" 顺序访问是硬件的"快车道",跳跃访问是"慢车道"。
第三,别只信 Big-O,要信 Profiler。 复杂度分析给你"理论形状",性能分析器(perf、VTune、Instruments、pprof)告诉你"真实瓶颈"。很多时候,优化运算次数一无所获,优化一次意外的缓存未命中却能翻倍。用数据定位,而不是用直觉猜。
第四,重新理解"过早优化是万恶之源"。 Knuth 这句话常被误读成"别优化"。它的真实含义是:别在 97% 不重要的地方瞎优化。而"让数据访问对缓存友好"恰恰属于那重要的 3%——它不是过早优化,而是从一开始就该有的工程直觉。
第五,对你的应用场景对号入座。 写后端服务,关注数据结构是否缓存友好、是否避免伪共享;写游戏/图形,拥抱数据导向设计;写 AI 推理,关心内存带宽和算子融合;写数据库,理解每种存储引擎(B+ 树、LSM、列存)如何与存储层级博弈。内存墙是所有这些领域的共同战场。
现代计算机的性能瓶颈不在"算",而在"等数据"——真正的高性能编程,不是减少运算次数,而是让数据离 CPU 更近、访问更连续,顺着内存墙的物理法则去写代码。
本文由「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 等场景全覆盖。
