CPU 的局部性原理
在实际编程中,我们常会发现: 逻辑相同的代码,仅仅改变数据访问顺序,性能却可能相差数倍。
造成这种差异的根本原因,正是现代 CPU 的核心设计思想之一——局部性原理(Locality Principle)。
随着学习从'会写代码'走向'写出高性能代码',我们会发现: 真正影响程序速度的,往往不是算法本身,而是内存访问模式与缓存命中率。
本文将围绕局部性原理展开,系统讲解:
- 什么是局部性原理
- 时间局部性与空间局部性的区别
- CPU 缓存如何利用局部性
- 代码访问方式为何会显著影响性能
帮助你理解程序性能与底层硬件之间的真实联系。
一、什么是局部性原理?
局部性原理(Locality Principle) 是指在程序运行过程中,所访问的指令和数据往往集中在较小的区域内,而不会随机分布在整个内存空间中。
换句话说:
程序的访问行为有'偏好',更倾向于访问'刚刚访问过'或'靠近刚刚访问过'的内存区域。
这种规律来源于:
- 程序的控制结构(循环、函数调用)
- 数据结构的访问方式(数组、指针、链表等)
- 编译器生成代码的局部性优化
因此,CPU 可以利用这一规律,通过在缓存中保存近期访问的数据或指令,极大提高访问速度。
二、局部性原理的两种类型
1. 时间局部性(Temporal Locality)
如果一个数据项被访问过,那么它很可能在不久的将来再次被访问。
典型场景:
int sum = 0;
for (int i = 0; i < 1000; ++i) {
sum += a[i];
}
- 变量
sum每次循环都会被访问(修改一次、读取一次)。 - 数组
a[i]的每个元素虽然只访问一次,但循环体代码在短时间内不断执行。
因此:
sum展现了强时间局部性。- 循环体指令也有时间局部性,因为 CPU 在短时间内反复执行同一段指令。
2. 空间局部性(Spatial Locality)
如果程序访问了某个地址的数据,那么它很可能在不久之后访问与该地址相邻的数据。
典型场景:
for (int i = 0; i < 1000; ++i) {
sum += a[i];
}
- 当 CPU 访问
a[0]时,极有可能紧接着访问a[1]、……


