memory
Outlinks (0)
No outlinks found
Backlinks (1)
Backlinks (1)
1 · memory#
S CPU 与内存速度差距持续扩大,内存访问已成为程序性能的主要瓶颈 C 硬件设计者引入了缓存等加速技术,但这些技术需要程序员配合才能发挥最佳效果;大多数程序员并不理解内存子系统的结构和代价 Q 程序员需要了解哪些内存知识,才能写出高性能代码? A 理解缓存层级、局部性原理、NUMA 拓扑,并在代码中应用数据局部性优化、预取、缓存行对齐、避免伪共享等技术
https://people.freebsd.org/~lstewart/articles/cpumemory.pdf Ulrich Drepper, “What Every Programmer Should Know About Memory”, 2007
1.1 · 硬件基础 (§2)#
- SRAM(快、贵、用于缓存)vs DRAM(慢、便宜、用于主存)
- 内存控制器架构:北桥(Northbridge)连接 CPU 与内存
- UMA(统一内存访问)vs NUMA(非一致性内存访问)
- DMA:网卡、存储控制器等设备直接访问内存,绕过 CPU
1.2 · CPU Cache (§3)#
- 缓存层级:L1i(指令)/ L1d(数据)、L2、L3
- 缓存行(cache line):缓存操作的最小单位(通常 64 字节)
- 关联度:直接映射 / N 路组相联 / 全相联
- 写策略:
- write-through:写缓存同时写主存,简单但慢
- write-back:只标记 dirty,驱逐时才写回,性能更好
- MESI 缓存一致性协议:Modified / Exclusive / Shared / Invalid 四状态
- dirty cache line 不会同时存在于多个处理器缓存中
- clean 副本可以存在于任意多个缓存中
- 伪共享(false sharing):不同核心写同一缓存行的不同变量,导致缓存行频繁失效
1.3 · 虚拟内存 (§4)#
- 多级页表(最多 4 级),稀疏树结构节省内存
- TLB(Translation Lookaside Buffer):缓存页表查询结果,避免每次访问都做页表遍历
- 大页(Huge Pages):减少 TLB miss,适用于大内存工作集
1.4 · NUMA (§5)#
- 每个 CPU 有本地内存,访问远端 CPU 的内存代价更高
- 内存亲和性:将数据和线程绑定到同一 NUMA 节点
1.5 · 程序员优化实践 (§6) ⭐#
- 数据局部性:顺序访问优于随机访问、结构体字段重排、冷热数据分离
- 预取(prefetch):硬件自动预取 + 软件预取指令(
__builtin_prefetch) - 缓存行对齐:
posix_memalign、__attribute__((aligned(64))) - 多线程优化:
- 避免伪共享:将不同线程写的数据放在不同缓存行
- CPU 亲和性:
cpu_set_t/sched_setaffinity绑定线程到特定核心
1.6 · 性能工具 (§7)#
cachegrind(Valgrind):模拟缓存行为,统计 L1/L2 miss 率oprofile/perf:利用硬件性能计数器采样- 关注比率而非绝对值(如每次调用的分支预测失败率)
1.7 · 展望 (§8)#
- 事务内存(transactional memory):用缓存实现原子操作,避免昂贵的主存写回