局部性
上文提到了局部性原理,在本文中将着重讨论一下局部性原理。
一个编写良好的计算机程序常常具有良好的局部性。
局部性通常可以分为两种不同的形式:时间局部性和空间局部性。
在一个具有良好时间局部性的程序中,被引用过一次的存储器位置很有可能在不远的将来被再次引用。在一个具有良好空间局部性的程序中,如果一个存储器位置被引用一次,那么程序很有可能在不远的将来引用附近的一个存储器位置。
举几个利用局部性原理的例子:
- 硬件中,引入了高速缓存存储器来保存最近被引用的指令和数据,从而提高对主存的访问速度。
- 操作系统中,用主存来缓存磁盘文件系统中最近被使用的磁盘块。
- web浏览器将在最近引用的文档放在本地磁盘上。
int sum(int v[8])
{
int i;
int sum=0;
for(i=0;i<8;i++)
{
sum+=v[i];
}
return sum;
}
v0 v1 v2 v3 v4 v5 v6 v7
1 2 3 4 5 6 7 8
汇编
sum:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl $0, -8(%ebp)
movl $0, -4(%ebp)
jmp .L2
.L3:
movl -4(%ebp), %eax
leal 0(,%eax,4), %edx
movl 8(%ebp), %eax
addl %edx, %eax
movl (%eax), %eax
addl %eax, -8(%ebp)
addl $1, -4(%ebp)
.L2:
cmpl $7, -4(%ebp)
jle .L3
movl -8(%ebp), %eax
leave
ret
首先看汇编代码,代码循环执行数组v元素求和。代码占用了57个字节,完全可以被高速缓存存储器缓存。因为是循环所以最近被访问的字节会被再次访问,这体现了时间局部性。循环包含了少量指令,临近的指令会被多次访问,这体现了空间局部性。
再看c代码代码循环相加了数组v中的元素,这循环遍历了数组v中的元素,所以说代码有空间局部性,而sum在每次循环中引用一次,有良好的时间局部性。
从上文可以看出,如果自己在写代码时注意局部性原理,那你的代码将得到极快的提升。