性能隐藏的引擎:数据存放在哪里决定一切
1. 性能的真正秘密:数据放在哪里决定一切
2. 决定系统快慢的不是 CPU,而是数据的距离
3. 缓存才是现代计算性能的核心
4. 忽视数据局部性,一切性能优化都是徒劳
5. 性能瓶颈不在算力,而在内存层级
6. 数据局部性:被低估的性能决定因素
7. CPU 在等你的内存:缓存层级的真实代价
8. 系统速度快的真正原因:一切都与缓存有关
9. 别再关注 CPU 速度了——数据局部性才是制胜关键
10. 为什么缓存是所有高性能系统的幕后引擎
11. 性能的关键不在于 GHz,而在于距离
12. 你的 CPU 正在等待内存:缓存不为人知的故事
13. 数据局部性:计算机领域最重要却鲜为人知的因素
14. 数据存储位置决定一切
15. 缓存主宰一切:性能指南
16. 内存层次结构:性能的隐形杀手(或救星)
17. 为什么现代性能之战是与延迟的较量,而非与计算能力的较量
我们喜欢讨论 CPU 频率,但在实际系统中,关键问题是:你的数据存放在哪里?
现代 CPU 依赖一个分层的内存体系(寄存器 → L1 → L2 → L3 → DRAM)。L1 访问可能只需约 4 个周期;而 DRAM 访问可能需要 200+ 个周期——那是 50× 更慢。如果你的工作集能放进缓存,一切飞快;如果不能,CPU 就会阻塞等待。
为什么缓存主导一切
分组处理是一个典型例子。每个数据包都会触发表查找。如果这些表能保持在缓存中,你可以每秒处理数百万个包;一旦溢出到 DRAM,吞吐量会崩塌。
真正的设计问题: 它能放进缓存吗?
缓存不仅仅关乎数据。指令缓存未命中也会毁掉尾延迟。有些高频交易系统会让热路径持续执行,只在需要发包时才打开网卡,从而保持 指令缓存持续命中。在交易环路中,一个 I-cache 停顿就可能占据全部延迟预算。
抽象失灵的地方
“全都上云”这类高层策略常忽略底层现实。虚拟化网络功能依赖于诸如:
- 独占核亲和(core pinning) —— 保持线程在同一 CPU 上以维持缓存热度
- 中断合并(interrupt coalescing) —— 降低中断率但以延迟为代价
- NUMA 局部性 —— 跨插槽访问会严重削弱性能
- 物理网卡与虚拟网卡 行为不同
销售演示会说“可以工作”,但细则通常是:需要 3 倍硬件、3 倍许可证,性能仍然无法与裸机匹配。 一旦你依赖缓存行为、核亲和和 NUMA 局部性,平台就不再可互换。
AI 也碰到同样的问题
即便在 AI 领域,物理规律也没变。模型越来越大,但数据移动依旧主导计算。局部性仍然是王道。
- 数组优于指针密集的结构,因为内存是连续的
- 硬件预取器只有在访问可预测时才有用
- 当内存布局合理时,缓存行被更高效地利用
在机器人控制中也能看到
在多轴运动控制中,第一个轴会“预热”缓存并承担缺失惩罚;后续轴的计算因为数据已经热化而耗时减半。相同的原理:局部性 = 速度。
IBM Telum:不同量级的缓存
IBM 的 Telum 处理器把这个想法推到了极端:
- 十个 36 MB 的 L2 缓存
- 360 MB 的虚拟 L3
- 2.8 GB 的虚拟 L4
该架构可以按需将 L2 转作 L3 使用。IBM 尚未公开这些缓存层的具体访问延迟,但在如此大规模的缓存下,大小、互连距离与命中延迟之间的折衷会非常有趣。
结论
性能归根结底由数据和指令能离核心多近来决定。
为局部性而设计,你的系统会表现出色。忽视它,再多的 GHz 或再多的云抽象也救不了你。
我们经常谈论 CPU 速度,却很少关注数据存储的位置。
性能主要取决于数据存储的便利程度。寄存器、L1 缓存、L2 缓存、L3 缓存、主内存——每一步都会增加延迟并降低吞吐量。访问主内存可能需要 200 个时钟周期,比 L1 缓存慢 50 倍。
当工作集能够放入缓存时,代码运行速度极快。否则,CPU 只能等待。
在数据包处理中,这种差异决定了一切。每个数据包都会触发表查找。如果这些表保存在 缓存 中,您可以每秒处理数百万个数据包。否则,吞吐量将急剧下降。
所以,下次设计数据结构时,请问问自己:
它能放进缓存吗?
因为在对性能要求极高的系统中,缓存不仅仅是一种优化手段,它定义了整个系统。
而且不仅是数据,指令也一样!我见过高频交易工程师讨论他们的策略,他们将热路径编程为始终处于激活状态,并且只在数据包需要离开系统时才启用网卡。这样也能保持指令缓存处于热状态。
保持指令缓存处于热状态与保持数据缓存处于热状态同样重要,尤其是在对可预测性要求很高的工作负载中。优化热路径,使 CPU 始终保持在指令缓存中至关重要,因为即使是很小的停顿也可能导致尾延迟显著增加。这很好地提醒我们,架构设计的真正目的是尽可能地将指令和数据都放在靠近核心的位置。
很多技术决策者都固守一刀切的策略:例如……万物皆可云——他们认为任何虚拟化工作负载都可以在任何虚拟化环境中运行,底层硬件和虚拟化技术都只是商品而已。但这并不适用于虚拟化网络功能,因为厂商们早就知道,独占线程核心绑定可以让执行线程独占使用 CPU 缓存。厂商们也知道,在虚拟化环境中,中断合并可以降低“CPU 使用率”,但会增加延迟。他们了解 NUMA 局部性,甚至把这些都写进了文档里。当然,销售人员来了之后,他们希望与高层战略保持一致,使用最佳优化基准测试,然后就云或虚拟机管理程序支持的问题展开另一场不加任何细节的讨论。没错,这行得通*但附注:你需要三倍的许可证/硬件,而且仍然无法获得最佳性能。人们对底层性能如此缺乏兴趣,技能差距如此之大,以至于似乎只能通过增加抽象层和厂商来掩盖责任。如果珠穆朗玛峰是检验技术领导力还是厂商责任的试金石,那么我们很想知道,究竟是哪一方会坚持到底,还是会在山脚下卖羽绒服。完全正确。一旦你依赖缓存行为、核心绑定和NUMA局部性,平台就不再具有可互换性了。底层细节远比大多数高层策略重要得多。
大多数繁重的AI工作负载仍然会遇到相同的内存层次结构限制。模型规模不断扩大,但芯片内部数据传输的物理机制并没有发生太大变化。理解局部性仍然是获得良好性能的关键。
数组能够为CPU提供它真正需要的东西:连续的内存和可预测的访问模式。这意味着预取器可以真正发挥作用,缓存行可以得到高效利用,并且避免了分散结构带来的指针追踪惩罚。这是保持缓存友好性的最简单方法之一。
机器人多轴运动控制也是如此。第一个轴预热缓存并承受缓存未命中的影响,下一个轴的计算时间缩短了一半。
IBM Telum处理器可以验证这一点,它能够按需将L2缓存转换为L3缓存,并且L4缓存可以被任何其他CPU访问。此外,该芯片的时钟频率始终保持在 5.5 GHz。它包含十个 36 MB 的二级缓存¹,以及扩展的虚拟三级缓存(360 MB)和四级缓存(2.8 GB)。
这是一款令人着迷的芯片。与大多数架构相比,其缓存容量巨大,这让我不禁好奇这会对各级缓存的访问延迟产生怎样的影响。可惜的是,我找不到任何关于 Telum 缓存的公开延迟数据,否则我很想了解 IBM 在实际应用中是如何平衡缓存容量、交换空间距离和命中延迟的。
英文:The Hidden Engine of Performance: It’s All About Where the Data Lives (Cache is the King)
本文一共 2349 个汉字, 你数一下对不对.上一篇: 用 Python 学强化学习: Q-Learning 迷宫示例
下一篇: 组合数学: 简介一(帕斯卡三角/二项式系数)

