Tony Bai

一个程序员的心路历程

马上订阅 Tony Bai RSS 更新: http://feed.tonybai.com/

释放 Go 的极限潜能:CPU 缓存友好的数据结构设计指南

bigwhite
2025年10月16日 08:24
技术志AoSArrayofStructsbenchmarkCacheLineCacheMissCachePollutionCPU缓存DataLocalityDataOrientedDesignFalseSharingGogo1.26GolanggoroutineHyperThreadingL1缓存L2缓存L3缓存MechanicalSympathyMESINonUniformMemoryAccessNUMAperfpprofRAMruntimeSIMDsimd包SingleInstructionMultipleDataSOAStructofArrays主内存伪共享冷热数据分离分支预测器性能数据导向设计数据局部性数据结构设计机械共鸣物理核心硬件预取器缓存一致性协议缓存未命中缓存污染缓存行超线程逻辑核心
本文永久链接 – https://tonybai.com/2025/10/16/cpu-cache-friendly-in-go 大家好,我是Tony Bai。 “现代 CPU 很快,而内存很慢。” 这句看似简单的陈词滥调,是理解现代高性能编程的唯一“真理”。我们常常致力于优化算法的时间复杂度,却忽略了一个更为根本的性能瓶颈:数据在内存和 CPU 缓存之间的移动。一次 L1 缓存的命中可能仅需数个时钟周期(~1ns),而一次主内存的访问则需要超过上百个周期(~100ns),这之间存在着超过 100 倍的惊人差距(2020年数据,如下图,近些年内存速度提升,但与L1缓存相比依旧有几十倍的差距)。 访问延迟,来自参考资料2(2020年数据) 近年来,自从 Go 更换了新的技术负责人后,整个项目对性能的追求达到了前所未有的高度。从 Green Tea GC 的探索,到对 map 等核心数据结构的持续优化,再到即将在 Go 1.26 中引入的实验性 simd 包,无不彰显出 Go 团队提升运行时性能和榨干硬件潜能的决心。 在这个背景下,理解并应用“CPU 缓存友好”的设计原则,不再是少数性能专家的“屠龙之技”,而是每一位 Gopher 都应掌握的核心能力。即便算法完全相同,仅仅通过优化数据结构,我们就有可能获得 2-10 倍甚至更高的性能提升。这并非“过早优化”,对于性能敏感的系统而言,这是一种必要优化。 本文受Serge Skoredin的“CPU Cache-Friendly Data Structures in Go: 10x Speed with Same Algorithm”启发,将和大家一起从 CPU 缓存的第一性原理出发,并结合完整的 Go 示例与基准测试,为你揭示一系列强大的“数据驱动设计”(Data-Oriented Design) [...]