局部性原理

目录

一、什么是局部性原理

二、局部性原理的应用

(1)缓存结构

(2)循环的局部性原理

案例A:数组循环长数据引用的局部性

案例B:排序对数组遍历的影响

参考资料


一、什么是局部性原理

一个编写良好的计算机程序常常具有良好的局部性。也就是说。它们倾向于引用临近于其他最近引用过的数据项的数据项,或者最近引用过的数据项本身。这汇总倾向性,就被称为局部性原理,这是一个持久的概念,对硬件和软件系统的设计和性能都有着极大的影响。

之所以有这个规律,很多人认为原因是:程序的指令大部分时间是顺序执行的,而且程序的集合,如数组等各种数据结构是连续存放的。

局部性原理讲的是:在一段时间内,整个程序的执行仅限于程序的某一部分,相应地,程序访问的存储空间也局限于某个内存区域。主要分为两类:

  1. 时间局部性:如果程序中的某条指令一旦执行,则不久之后该指令可能再次被执行;如果某数据被访问,则不久之后该数据可能再次被访问。
  2. 空间局部性:是指一旦程序访问了某个存储单元,则不久之后,其附近的存储单元也将被访问。

二、局部性原理的应用

(1)缓存结构

CPU内部的ALU(运算器)进行信息的处理,寄存器进行信息的存储,总线连接各器件,进行数据的传送。

CPU内部组成及工作原理

 

存储器层次结构

将计算机分为数个层次:

  • 寄存器 64位

  • 一级缓存L1 4×64KB

  • 二级缓存L2 4×256KB

  • 三级缓存L3 8MB

  • 内存 4GB

  • 磁盘 1TB

寄存器是CPU的工作台,CPU在工作时,先从一级缓存里面找,找不到就从二级缓存里面找,依次类推。假如CPU到磁盘才有,那么这个数据就会存入内存,再存入三级缓存、二级缓存、一级缓存,最后存入寄存器,然后进行计算。所以说,可以这么看, L1是寄存器的缓存,L2是L1的缓存,依次这样下去,下面一层是上面一层的缓存。

由于各层存储之间的速度差异,CPU要高速工作,我们希望CPU需要的数据更多的就在L1里面,能够告诉获取到,不希望更多的跑到下面内存乃至磁盘里面去找,这样会花更多的时间。所以当CPU用了一个数据,计算机会遇见性的存入其他等会儿CPU可能会用到的数据到L123内存,用到的可能性越大,就能存到越接近寄存器的层次。这也才是缓存的真正意义。那么,计算机怎样才能判断一个数据接下来可能被用到?

时间局部性:如果一个信息项正在被访问,那么在近期它很可能还会被再次访问。所以数据在寄存器被计算完成后,将会放入告诉缓存中。

空间局部性:在最近的将来将用到的信息很可能与现在正在使用的信息在空间地址上是临近的。而且基于指令顺序执行的特性,大部分的数据存储被认为是连续的。所以程序在装载入内存时,不是整体装入,而是分块(页框)装入的。

(2)循环的局部性原理

对于诸如For循环,其在执行时也遵循一定的局部性原理,我们以案例来进行讲解。

案例A:数组循环长数据引用的局部性

private static void loopArray() {
	int[][] arrayC = new int[10000][10000];

	long startA = System.currentTimeMillis();
	int sum1 = 0;
	for (int i = 0; i < 10000; i++) {
		for (int j = 0; j < 10000; j++) {
			sum1 += arrayC[i][j];
		}
	}
	long endA = System.currentTimeMillis();
	System.out.println("  Array行遍历结果:" + sum1 + ", 耗时:" + (endA - startA)
			+ "ms");

	long startB = System.currentTimeMillis();
	int sum2 = 0;
	for (int i = 0; i < 10000; i++) {
		for (int j = 0; j < 10000; j++) {
			sum2 += arrayC[j][i];
		}
	}
	long endB = System.currentTimeMillis();
	System.out.println("  Array列遍历结果:" + sum2 + ", 耗时:" + (endB - startB)
			+ "ms");
}

执行结果:

  Array行遍历结果:0, 耗时:79ms
  Array列遍历结果:0, 耗时:1420ms

上述代码中,通过对一个10000 * 10000的二维数组进行遍历,分别从行、列两个主序维度,可以看出行遍历是列遍历效率的10倍以上。因为数组在内存中大多是顺序存放的,而多维数组主要是以行为主序进行存放,如下图所示。

preview

对于行维度(即相当于一维数组)来说,在空间上具有良好的空间局部性原理,即a[i]总是a[i-1]后一个位置存放。

但是对于列维度来说(以列序为主序遍历),意味着每访问一个元素,就要跳过N个元素才能访问下一个,这种情况下没有良好的空间局部性。所以在遍历时出现了明显的性能差异。

 

案例B:排序对数组遍历的影响

本案例主要涉及局部性原理和分支预测理论,故放在性能优化相关文章中,请参照:

性能优化之分支预测


参考资料

https://www.zhihu.com/question/25142664/answer/60733489

《码农翻身》——刘欣

局部性原理是计算机系统设计中的一个重要概念,指的是程序在执行过程中,对数据和指令的访问往往呈现出一定的空间和时间上的局部集中特点。根据局部性原理,计算机系统可以通过缓存(cache)机制来提高数据访问的效率。 Cache是一种高速存储器,位于CPU和主存之间,用于存放最近被访问过的数据和指令。Cache的工作原理是通过将主存中的一部分数据复制到Cache中,以便在下次访问时能够更快地获取数据。当CPU需要访问数据时,首先会在Cache中进行查找,如果命中则直接从Cache中获取;如果未命中,则需要从主存中读取数据,并将其存放到Cache中以供以后的访问。 Cache机制利用了程序执行过程中的局部性原理,主要包括以下两种局部性: 1. 时间局部性:指程序在某个时间点访问的数据与该时间点附近访问的数据存在较高的相关性。例如,循环结构中的变量访问、指令的顺序执行等。 2. 空间局部性:指程序在某个空间范围内访问的数据与该范围附近访问的数据存在较高的相关性。例如,数组遍历、连续内存空间的访问等。 通过Cache机制,可以将频繁访问的数据存放在高速Cache中,减少对主存的访问次数,从而提高数据访问效率。同时,Cache还可以使用替换策略来管理存储空间,以保证最常被访问的数据能够保持在Cache中。 总结起来,局部性原理和Cache机制是计算机系统中用于提高数据访问效率的重要手段。局部性原理描述了程序访问数据的空间和时间上的集中特点,而Cache机制则利用了这种局部性,将频繁访问的数据存放在高速Cache中,以加快数据访问速度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值