寄存地

In order to be irreplaceable, one must always be different

0%

Cache和Buffer的区别

Cache的核心作用是加快取用的速度。Buffer的核心作用是用来缓冲,缓和冲击。

Cache 是为了弥补高速设备和低速设备的鸿沟而引入的中间层,最终起到加快访问速度的作用。而 Buffer 的主要目的进行流量整形,把突发的大数量较小规模的 I/O 整理成平稳的小数量较大规模的 I/O,以减少响应次数

缓存工作的原则,就是“引用的局部性”,这可以分为时间局部性和空间局部性。空间局部性是指CPU在某一时刻需要某个数据,那么很可能下一步就需要其附近的数据;时间局部性是指当某个数据被访问过一次之后,过不了多久时间就会被再一次访问。对于应用程序而言,不管是指令流还是数据流都会出现引用的局部性现象。

Cache(缓存)是系统两端处理速度不匹配时的一种折衷策略。因为CPU和memory之间的速度差异越来越大,所以人们充分利用数据的局部性(locality)特征,通过使用存储系统分级(memory hierarchy)的策略来减小这种差异带来的影响。

1
2
3
4
5
6
举例:
假设某地发生了自然灾害(比如地震),居民缺衣少食,于是派救火车去给若干个居民点送水。救火车到达第一个居民点,开闸放水,老百姓就拿着盆盆罐罐来接水。假如说救火车在一个居民点停留100分钟放完了水,然后重新储水花半个小时,再开往下一个居民点。这样一个白天来来来回回的,也就是4-5个居民点。
但我们想想,救火车是何等存在,如果把水龙头完全打开,其强大的水压能轻易冲上10层楼以上, 10分钟就可以把水全部放完。但因为居民是拿盆罐接水,100%打开水龙头那就是给人洗澡了,所以只能打开一小部分(比如10%的流量)。但这样就降低了放水的效率(只有原来的10%了),10分钟变100分钟。
那么,我们是否能改进这个放水的过程,让救火车以最高效率放完水、尽快赶往下一个居民点呢?方法就是:在居民点建蓄水池。救火车把水放到蓄水池里,因为是以100%的效率放水,10分钟结束然后走人。居民再从蓄水池里一点一点的接水。
我们分析一下这个例子,就可以知道Cache的含义了。救火车要给居民送水,居民要从救火车接水,就是说居民和救火车之间有交互,有联系。但救火车是“高速设备”,居民是“低速设备”,低速的居民跟不上高速的救火车,所以救火车被迫降低了放水速度以适应居民。
为了避免这种情况,在救火车和居民之间多了一层“蓄水池(也就是Cache)”,它一方面以100%的高效和救火车打交道,另一方面以10%的低效和居民打交道,这就解放了救火车,让其以最高的效率运行,而不被低速的居民拖后腿,于是救火车只需要在一个居民点停留10分钟就可以了。

Buffer(缓冲区)是系统两端处理速度平衡(从长时间尺度上看)时使用的。它的引入是为了减小短期内突发I/O的影响,起到流量整形的作用。比如生产者——消费者问题,他们产生和消耗资源的速度大体接近,加一个buffer可以抵消掉资源刚产生/消耗时的突然变化。

1
2
3
葡萄熟了,要用大卡车装葡萄运出去卖。但问题是,卡车距离葡萄园很远,于是就需要在葡萄园和卡车之间往返多次才能把卡车装满。往返所需要的时间就是I/O延迟,比如往返各15分钟,总共半小时。
果园的姑娘采摘葡萄,难道是摘一串葡萄,就花15分钟跑到卡车旁边放进去么?如果是这样,100串葡萄就需要往返100次,所需要的时间就是100X15X2分钟,那是何其漫长!所以聪明的做法就是暂时把100串葡萄放入一个箩筐,再以箩筐为单位倒入卡车,一箩筐(100串)葡萄的往返延迟是半小时。
由此可见,“箩筐”把输入参数暂时集中放在一起,不是“一条一条”,而是“一股脑”地提供给下家处理。这就大大降低了I/O的次数,也就降低了I/O延迟,提高了速度。这个箩筐,就是Buffer。

假定以后存储器访问变得跟CPU做计算一样快,cache就可以消失,但是buffer依然存在。

1
TLB(Translation Lookaside Buffer,翻译后备缓冲器)其实是一个cache。

参考资料:

Cache 和 Buffer 都是缓存,主要区别是什么?