程序访问的局部性原理
局部性是整个存储层次结构赖以成立的唯一前提(见 3.1.3)。它不是一条硬件设计原则,而是一条对程序行为的经验观察:程序在一小段时间里访问的地址,总是集中在一小片区域内。
正因为它是关于程序的,所以它可以被程序员改变。 这是本节最有价值的一点——同一台机器、同一个 Cache,改一下循环的嵌套顺序,命中率能差一个数量级,2014 年的统考真题考的就是这件事。
机制
两种局部性
时间局部性:刚被访问过的地址,很可能马上又被访问。
- 来源:循环(循环体的指令、循环变量、累加器变量)
- 硬件对策:把访问过的内容留在 Cache 里
空间局部性:刚被访问过的地址,它附近的地址很可能马上被访问。
- 来源:指令的顺序存放与顺序执行、数组元素的连续存放
- 硬件对策:一次装入一整块(Cache 行),而不是一个字
两种局部性各自对应 Cache 的一个设计决策:时间局部性决定”要不要留”,空间局部性决定”一次装多大”。块大小的选择就是在空间局部性上下注,见 3.5.2。
指令与数据分别看
指令流的局部性几乎总是很好:顺序执行给出空间局部性,循环给出时间局部性。
数据流的局部性差别巨大,取决于访问模式:
| 访问模式 | 空间局部性 | 例子 |
|---|---|---|
| 顺序遍历数组 | 好 | for(i) a[i] |
| 跨步长遍历 | 随步长增大而变差 | for(i) a[i*N] |
| 随机访问 | 差 | 哈希表、链表追指针 |
疑问点:循环体的时间局部性好,是因为"没有跳转"
这个判断把两种局部性的来源接反了。
空间局部性来自”没有跳转”——指令在主存中顺序存放,顺序执行时下一条指令就在旁边,所以取一个块能覆盖后面好几条指令。 时间局部性恰恰来自”有跳转”——循环末尾那条回边把 PC 拉回循环开头,同一段指令被重复执行了
次。若真的没有跳转、程序一路直线执行下去,每条指令只执行一次,时间局部性反而为零。 一句话概括:顺序执行给空间局部性,循环回跳给时间局部性。 循环体两者兼得,正是因为它既是顺序的、又是重复的。
这道 2014 年真题的设问方式值得单独记住。 题目给的两个程序只在循环嵌套顺序上不同(一个按行遍历二维数组、一个按列遍历),因此: 指令部分完全相同——都是同样的二重循环、同样的指令条数,指令 Cache 的命中率一样; 数据部分差别极大——按行遍历顺着数组在内存中的存放顺序走,空间局部性好;按列遍历每次跨过一整行,每访问一个元素就换一个 Cache 块,空间局部性极差。 所以这道题的正确回答是”指令局部性相同、数据局部性不同”,而不是笼统地说”两个程序局部性一样”或”不一样”。
局部性可以被写出来
二维数组在 C 语言中按行优先存放,因此:
for (i = 0; i < N; i++) for (j = 0; j < N; j++)
for (j = 0; j < N; j++) for (i = 0; i < N; i++)
sum += a[i][j]; sum += a[i][j];
↑ 按行,空间局部性好 ↑ 按列,每次跨一整行
设 Cache 块能装
这就是”局部性是程序的属性”的全部含义:硬件只能被动地利用它,创造它的是代码。
边界
局部性是统计规律,不是保证。 它对绝大多数程序成立,但对精心构造的反例可以完全失效——例如步长恰好等于 Cache 容量除以相联度的遍历,会让每次访问都冲突缺失(见 3.5.3)。“Cache 一定能提高速度”是错的。
“局部性好”必须说清是哪一种、哪一部分。 一道题问”两个程序的局部性是否相同”,必须分指令与数据、分时间与空间四格来答,笼统地说”一样”或”不一样”都不得分。
空间局部性的度量是”步长”,不是”访问了多少数据”。 遍历一个 1 GB 的数组,只要是顺序的,空间局部性就好。
局部性同时是 Cache 和虚拟存储器的前提。 页式虚拟存储器的工作集概念、缺页率随驻留集大小的变化,全部建立在同一条规律上,见 OS 3.2.5 抖动与工作集。
对照速查
| 时间局部性 | 空间局部性 | |
|---|---|---|
| 内容 | 刚访问的还会再访问 | 刚访问的附近会被访问 |
| 指令的来源 | 循环回跳 | 顺序存放与执行 |
| 数据的来源 | 反复使用的变量 | 数组连续存放 |
| 硬件对策 | 保留在 Cache 中 | 按块装入 |
| 相关设计 | 替换算法 | 块大小、预取 |
考点
- 层次存储器成立的唯一前提是局部性
- 顺序执行 → 空间局部性;循环回跳 → 时间局部性(两者不能接反)
- 指令局部性通常好,数据局部性取决于访问模式
- 按行/按列遍历二维数组,指令局部性相同、数据局部性差别极大
- 空间局部性决定块大小,时间局部性决定要不要保留
- 局部性是程序的属性,硬件只能利用不能创造
- 答”局部性是否相同”要分指令/数据、时间/空间四格
链接
- 🏠 返回总览:计算机组成原理第 3 章:存储系统总览
- ⬅️ 上一节:3.4.2 固态硬盘
- ➡️ 下一节:3.5.2 Cache 的基本工作原理
- 🔗 3.1.3 多级层次的存储系统(局部性支撑的对象)
- 🌐 跨科:OS 3.2.5 抖动和工作集
- 📖 名词库:第 3 章名词库