高速缓存以及相关的几种算法的小结

缘由

今日读完深入理解nginx的第二章,没什么难度。都是一些配置上的问题,但其中一个LRU算法引起了我的注意。所以稍稍对此知识扩展了一下。
参考资料:

高速缓存

高速缓存(英语:Cache),其原始意义是指访问速度比一般随机存取存储器(RAM)快的一种RAM,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。如下图所示(来自深入理解计算系统):



提出这项技术的原因是当CPU处理数据时,如果在寄存器中不存在,那么它会先到Cache中去寻找,如果数据因之前的操作已经读取而被暂存其中,就不需要再从随机存取存储器(Main memory,就是说我们所说的内存)中读取数据——由于CPU的运行速度一般比主内存的读取速度快,主存储器周期(访问主存储器所需要的时间)为数个时钟周期。因此若要访问主内存的话,就必须等待数个CPU周期从而造成浪费。

然而,如今高速缓存的概念已被扩充,不仅在CPU和主内存之间有Cache,而且在内存和硬盘之间也有Cache(磁盘缓存),乃至在硬盘与网络之间也有某种意义上的Cache──称为Internet临时文件夹或网络内容缓存等。凡是位于速度相差较大的两种硬件之间,用于协调两者数据传输速度差异的结构,均可称之为Cache。如下表所示(来自深入理解计算系统):



如此一来,我们又面临了新的问题,那就是主存容量远大于CPU高速缓存,磁盘容量远大于主存,因此无论是哪一层次的缓存都面临一个同样的问题:当容量有限的缓存的空闲空间全部用完后,又有新的内容需要添加进缓存时, 如何挑选并舍弃原有的部分内容,从而腾出空间放入这些新的内容。解决这个问题的算法有几种,如最久未使用算法(LRU)、先进先出算法(FIFO)、最近最少使用算法(LFU)、非最近使用算法(NMRU)等,这些算法在不同层次的缓存上执行时拥有不同的效率和代价,需根据具体场合选择最合适的一种。

LRU

LRU算法(Least Recently Used,最久未使用算法)的提出,是基于这样一个事实:在前面几条指令中使用频繁的页面很可能在后面的几条指令中频繁使用。反过来说,已经很久没有使用的页面很可能在未来较长的一段时间内不会被用到。因此,我们只需要在每次调换时,找到最少使用的那个页面调出内存。这就是LRU基本思想。
此外,如果使用纯粹的随机替换法。测试表明完全随机替换的性能近似于LRU。

通过一个例子,我想更能说明问题。大家都知道内存和磁盘之间有一个高速缓存叫作:虚拟内存。在内存中认为暂时不使用的,就可以先放入到虚拟内存中,虚拟内存实际使用磁盘中的空间。那么在内存和虚拟内存之间的交互的数据的大小如果为一页的话,就是
虚拟页式存储)(内外存信息的替换是以页面为单位进行的)。下面的例子中,我们采用计算的1、2、3、4....代表需要的一页。
  1. 首先 假设需要使用的页面顺序为为:4 3 4 2 3 1 4 2
  2. 假设内存中最多只能放3个页面
  3. 首轮 4调入内存 4
  4. 次轮 3调入内存 3 4
  5. 之后 4调入内存 4 3
  6. 之后 2调入内存 2 4 3
  7. 之后 3调入内存 3 2 4
  8. 之后 1调入内存 1 3 2(因为最少使用的是4,所以丢弃4)——LRU算法
  9. 之后 4调入内存 4 1 3(原理同上)
  10. 最后 2调入内存 2 4 1

LFU

最不经常使用置换算法(least frequently used (LFU)),其原理也比较简单:对每一页额外维护一个变量,计算其被使用的次数,那么当然发生置换时:要求在页置换时置换引用计数最小的页。

然而,这样的做法有着明显的缺陷:些页在开始时使用次数很多,但以后就不再使用,这类页将会长时间留在内存中。

应对策略是:可以将引用计数寄存器定时右移一位,形成指数衰减的平均使用次数。

NRMU

非最近使用(NMRU)是一个与最久未使用算法相似的算法。这个算法仅记录哪一个缓存块是最近被使用的。在替换时,会随机替换掉任何一个其他的块。故称非最近使用。相比于LRU,这种算法仅需硬件为每一个缓存块增加一个使用位(use bit)即可。

FIFO

先进先出算法(FIFO)替换掉进入组内时间最长的缓存块。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值