【计算机系统】局部性
(一)理解局部性:
时间局部性:被引用过一次的内存位置,很有可能在不远的将来再次被引用。(引用可以理解为访问)
空间局部性:
步长
决定空间局部性的好坏,一般而言:步长越大,空间局部性越差。顺序引用模式:步长为1的引用模式,例如一维数组(具有连续内存空间的数据结构)、二维数组(行优先)
(二)为什么要引入局部性?
局部性好的程序比局部性差的程序运行的更快。(原因后期补充:先挖个坑)
举个例子:对一维数组的所有元素进行求和
1 | int SumArr(int* arr, int len) |
分析:
- 对于sum来说,具有较好的时间局部性(访问频率高),不具备空间局部性(sum是标量)
- 对于arr来说,具有很好的空间局部性(地址连续,访问速度快),时间局部性差(arr每个元素只使用一次)
关键的变量 | 时间局部性 | 空间局部性 |
---|---|---|
sum | 好 | 无 |
arr | 差 | 好 |
结论:对于一个程序来说,要么具有好的时间局部性,要么具有好的空间局部性,该程序具有较好的局部性
1. 小试身手
(1)行优先:对一个二维数组所有元素求和
1 | //int Sum2DArr(int (*parr)[col], int row, int col) |
分析:
关键的变量 | 时间局部性 | 空间局部性 |
---|---|---|
sum | 好 | 无 |
parr | 差 | 好 |
2. 小试身手
(1)列优先:对一个二维数组所有元素求和
1 | //int Sum2DArr(int (*parr)[col], int row, int col) |
分析:
关键的变量 | 时间局部性 | 空间局部性 |
---|---|---|
sum | 好 | 无 |
parr | 差 | 差 |
结论:在对二维数组元素访问时采用列优先时,此时的步长为col, 访问的方式是parr[0][0]、 parr[1][0]......
(三)取指令的局部性
取指令:操作系统将该程序从就绪态转成运行态的过程中,会进行读取将程序的段加载到内存中,CPU会从存放指令段的内存地址中读取对应的程序的指令的过程。
对于上面写的程序来说,都使用了循环,那么对于循环内的指令来说,具有好的时间局部性(多次访问)
、好的空间局部性(指令存放内存的位置较为集中连续,引用步长小)。
(四)局部性总结
量化局部性的原则:
- 重复引用相同变量的程序具有较好的时间局部性;
- 对于具有步长为N的引用模式的程序,步长越小,空间局部性就越好
- 对于取指令来说,循环具有良好的时间和空间局部性。循环体越小,迭代次数越多,局部性越好
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 code-016!