3-3存储系统-高速缓冲存储器Cache

Posted 卡__卡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3-3存储系统-高速缓冲存储器Cache相关的知识,希望对你有一定的参考价值。

文章目录

一.概述

高速缓冲存储器(Cache):介于主存和CPU之间,用来存放正在执行的程序段和数据,以便CPU能高速地使用它们。
Cache的存取速度和CPU的速度相匹配。容量小,价格高,速度介于主存和CPU之间。现代计算机通常将其制作在CPU中。


1.局部性原理
(1)空间局部性
在最近的未来要用到的信息(指令和数据),很可能与现在正在使用的信息在存储空间上是邻近的。如数组元素、顺序执行的指令代码
(2)时间局部性
时间局部性:在最近的未来要用到的信息,很可能是现在正在使用的信息。如循环结构的指令代码

2.平均访问时间
设访问一次Cache所需时间为A,访问一次主存所需时间为B;欲访问信息在Cache中的比率(命中率)为P,未命中率(缺失率)为1-P
①先访问Cache,未命中再访问主存:Cache-主存系统的平均访问时间=AP+(1-P)(A+B)
②同时访问Cache和主存:平均访问时间=AP+B(1-P)

3.基于局部性原理,可以把主存的存储空间分块(如1KB),主存和Cache间以块为单位进行数据交换。当访问某一地址时,将整个块的信息调入Cache(每次被访问的主存块,一定会被立即调入Cache)

将主存空间分块,Cache也分为大小相同的块

主存地址可以用(块号,块内地址)表示

主存的“块”又叫“页/页框/页面”;Cache的“块”又叫“行”

二.Cache与主存的映射方式

解决主存和Cache数据块的映射关系(对应关系)。

1.直接映射

主存中的每一个块只能装入Cache中的唯一(特定)位置。若该位置有内容,则替换出去。

优点:实现简单
缺点:不够灵活,可能造成冲突且冲突概率高,即使后面有空间也可能不用,空间利用率低

装入位置(Cache块号)=主存块号%Cache总块数

地址结构(标记,Cache行号,块内地址)
①标记:用来记录当前Cache块存放的数据来自于哪个主存块,若当前空闲标记记录为0(为防止看成是来自于0号主存块,需要增加有效位表示是否有效。如有效位1,标记0,表示当前来自于0号主存块;有效位0标记0表示当前块空闲)。

注:标记用二进制位表示,位数与主存块号位数相同。一般Cache的行数是2的整数次幂,即Cache行数=2n,即主存块号末尾的n位表示存储在Cache的行数(如n=3,主存块号末尾3位表示存储在Cache的哪一行,对于0、8…的末尾3位都是0,都存储在第0号Cache块)。可以看出,主存块号末尾的n位直接反应了它在Cache中的位置,因此为节省存储空间,标记可不存储主存块号的末尾n位,将其余位作为标记即可



在此例中将地址结构进一步划分

②Cache行号:对Cache各块从0开始编号。主存的第0、1、2、3号块依次映射到Cache块的第0、1、2、3行

2.全相联映射

主存中的每一块可以装入Cache中的任何位置,每行的标记用于指出取自主存的哪一块,所以CPU访存时需要与所有Cache行的标记进行比较。如:主存块号22位,块内地址6位。当CPU访问某主存地址时,将前22位和Cache的标记对比,若相同,再检查有效位,若有效即可访问块内地址指定的地址单元。若Cache未命中,则正常访问主存查找。

优点:比较灵活,Cache块的冲突概率低,空间利用率高,命中率高
缺点:标记比较的速度较慢,实现成本高。通常需要采用按内容寻址的相联存储器进行地址映射

地址结构:(标记,块内地址)

3.组相联映射

将Cache空间分成大小相同的组,主存的一个数据块可以装入一组内的任何位置,即组间采用直接映射(指定),组内采取全相联映射(任意)。
组号=主存块号%分组数

2路组相联映射:两个Cache块为一组,在此例中Cache被分为四组,即22,因此可以通过主存块号的最后两位判断属于哪个分组

CPU访存时,先找属于哪个分组(根据主存块号后n位判断),然后在指定分组中逐块对比,找到后检查有效位,若有效,即可访问块内地址指向的存储单元。若未命中则正常访问主存

三.Cache中主存块的替换算法

Cache很小,主存很大。如果Cache满了,需要使用替换算法换入和换出。直接映射不需要考虑替换算法,全相联映射当Cache全满时才需要替换(全局替换),组相联映射当组满时才需要替换(组内替换)。

分为随机算法RAND、先进先出算法FIFO、最近最少使用算法LRU、最不经常使用算法LFU

对比操作系统的页面置换算法:最佳置换算法OPT、先进先出页面置换算法FIFO、最近最久未使用置换算法LRU、时钟置换算法CLOCK / 最近未用算法NRU、改进型时钟置换算法
操作系统的页面置换算法见:3-2内存管理-虚拟内存

1.随机算法RAND

随机确定替换的Cache块。实现简单,可能命中率较低。

2.先进先出算法FIFO

选择最早调入的行进行替换。实现容易,但最早调入的主存块可能也是最经常使用的

抖动现象:频繁的换入换出现象(刚被替换的块很快又被调入)

3.最近最少使用算法LRU

Least Recently Used
往前找最近未使用过的块(手算)。选择近期内长久未访问过的Cache行作为替换的行。命中率比FIFO高,遵循了局部性原理,是堆栈类算法。若频繁访问主存块的数量大于Cache行的数量,也会产生抖动现象。

也可每行设置一个计数器(初始为0)(机器计算方式)
优势:Cache块的总数=2n,则计数器只需n位。且Cache装满后所有计数器的值一定不重复

规则:
①命中时,所命中的行的计数器清零,比其低的计数器加1,其余不变
②未命中且还有空闲行时,新装入的行的计数器置0,其余非空闲行全加1
③未命中且无空闲行时,计数器值最大的行的信息块被淘汰,新装行的块的计数器置0,其余全加1

[例] 设总共有4个Cache块,初始整个Cache为空。采用全相联映射,依次访问主存块1,2,3,4,1,2,5,1,2,3,4,5

①访问1号主存块,未命中。当前还有空闲行,新装入的行的计数器置0(Cache #0的计数器)。无其他非空闲行,不做处理

②访问2号主存块,未命中。当前还有空闲行,新装入的行的计数器置0。其余非空闲行全加1,Cache#0的计数器由0改1

③访问3号主存块,未命中。当前还有空闲行,新装入的行的计数器置0。其余非空闲行全加1,Cache#0的计数器由1改2,Cache#1的计数器由0改1

④访问4号主存块,未命中。当前还有空闲行,新装入的行的计数器置0。其余非空闲行全加1,Cache#0的计数器由2改3,Cache#1的计数器由1改2,Cache#2的计数器由0改1

⑤访问1号主存块,命中。所命中的行的计数器清零(Cache#0),比其低的计数器加1(Cache#123的计数器分别为321),其余不变

⑥访问2号主存块,命中。所命中的行的计数器清零(Cache#1),比其低的计数器加1(Cache#023的计数器分别为132),其余不变


⑦访问5号主存块,未命中,且无空闲行。计数器值最大的行的信息块被淘汰(Cache#2),新装行的块的计数器置0,其余全加1(Cache#013的计数器分别为213)

⑧访问1号主存块,命中。所命中的行的计数器清零(Cache#0),比其低的计数器加1(Cache#12的计数器分别为21),其余不变(Cache#3)

⑨访问2号主存块,命中。所命中的行的计数器清零(Cache#1),比其低的计数器加1(Cache#02的计数器分别为12),其余不变(Cache#3)

⑩访问3号主存块,未命中,且无空闲行。计数器值最大的行的信息块被淘汰(Cache#3),新装行的块的计数器置0,其余全加1(Cache#012的计数器分别为213)

⑪访问4号主存块,未命中,且无空闲行。计数器值最大的行的信息被淘汰(Cache#2),新装行的块的计数器置0,其余全加1(Cache#013的计数器分别为321)

⑫访问5号主存块,未命中。计数器值最大的行的信息被淘汰(Cache#0),新装行的块的计数器置0,其余全加1(Cache#123的计数器分别为312)

4.最不经常使用算法LFU

Least Frequently Used
将一段时间内被访问次数最少的存储行换出。每行设置计数器(初始为0),每访问一次计算器加1,选择计数器最小的换出。可能导致计数器的值过大,且曾经被经常访问的主存块在未来不一定会用到(LFU属于全局考虑,并非局部性考虑),因此实际中不如LRU

当两个同时(相等)最小时,可以按照FIFO算法换出,也可选择行号较小的先换出

【LRU与LFU对比】
(1)最近最少使用算法LRU(Least Recently Used):考察的是从页面最后一次被使用 到发生替换的时间长短,时间越长,页面就会被置换。LRU是(往前看)淘汰最长时间没有被使用的页面。
(2)最不经常使用算法LFU(Least Frequently Used):考察在一段时间内,使用次数(访问频率)最少的页面淘汰。

四.Cache写策略

Cache中的数据只是主存数据的副本,当Cache内容更新时,需选用写操作策略使Cache内容和主存内容保持一致。


在写策略中,一定对数据进行了修改

1.写命中

在磁盘/内存的存储区域上写过数据,且此次还要在相同地方写入数据。在此情况下,CPU要写入数据的主存块副本已经存在于Cache中,即待修改的内容可在Cache中直接找到,修改时不需要再访问主存

(1)全写法/写直通法
当CPU对Cache写命中时,必须把数据同时写入Cache和“主存”,一般使用写缓冲。当Cache块被换出时,也不需要将其再写回主存。

此方法实现简单,能随时保持主存数据的正确性。但增加了访存次数,降低了Cache的效率。

写缓冲:为减少全写法直接写入主存的时间损耗,在Cache和主存之间增加了一个写缓冲。CPU同时写数据到Cache和写缓冲中,写缓冲再控制将内容写入主存。写缓冲是一个FIFO队列,可以解决速度不匹配的问题,但可能存在写缓冲饱和导致阻塞。

(2)写回法
当CPU对Cache写命中时,只修改Cache的内容,而不立即写入主存,只有当此块被换出时才写回主存。若未命中,则不需要写回主存。

使用此方法可以减少CPU的访存次数,但可能存在数据不一致的情况(不立即写回主存)。

需要给每一个Cache块增加一个“脏位”,若修改过,脏位置1,否则置0。标记决定了写回到主存的什么位置。

2.写不命中

在磁盘/内存的存储区域的相同位置没有写过数据。在此情况下,CPU要写入数据的主存块不在Cache中,即待修改的内容在Cache中找不到,需要去主存中查找

(1)写分配法
当CPU对Cache写不命中时,把主存中的块调入Cache,在Cache中修改,再搭配写回法,当Cache块被换出时将其写回主存

(2)非写分配法
当CPU对Cache写不命中时,不调入Cache,直接往主存中写入数据。通常搭配全写法。在此方式下,仅读未命中时,才将其调入Cache

【多级Cache】
离CPU越近的速度越快,容量越小
离CPU越远的速度越慢,容量越大

Cache-主存之间常采用“写回法+写分配法”
各级Cache之间常采用“全写法+非写分配法”

  • 什么是Cache
    Cache用到的是利用程序访问的局部性原理的高速缓冲技术,我们将程序中正在使用的部分存放在一个高速的、容量较小的Cache中,使CPU的访存操作大多数针对Cache进行,从而大大提高程序的执行速度。
  • 简述Cache的映射方式
    Cache映射方式分为直接映射、全相联映射和组相连映射。
    ①直接映射是每个主存块只能装入Cache中的唯一位置,若这个位置已经有内容则会替换掉原来的块。虽然实现简单,但是不够灵活,而且冲突概率最高,空间利用率最低。
    ②全相联映射可以把主存块装入Cache中的任何位置。优点是比较灵活,而且冲突概率地低,空间利用率高,命中率也高。缺点是地址变换速度慢,因为用到昂贵的按内容寻址的相联存储器进行地址映射,所以实现成本高。
    ③组相连映射是把Cache空间分为大小相同的组,主存的一个数据块可以装入一组内任何一个位置。即组间采取直接映射,组内采取全相联映射。其综合了直接映射和全相联映的优点
  • 简述Cache替换算法
    Cache替换算法分为随机算法RAND、先进先出算法FIFO、最近最少使用算法LRU、最不经常使用算法LFU
    ①随机算法是随机确定替换的Cache块,实现简单,但是命中率也很低。
    ②先进先出算法选择最早调入的行进行替换。比较容易实现,但是不遵循局部性原理。
    ③近期最少使用算法LRU依据局部性原理来替换近期内长久未访问过的存储行,是堆栈类算法。
    ④最不经常使用算法将一段时间内被访问次数最少的存储行换出。
  • 简述Cache写策略
    Cache写策略分为写命中和写不命中的情况
    ①写命中有两种处理方法:全写法和写回法。全写法是当CPU对Cache写命中时,必须把数据同时写入Cache和主存。写回法是当CPU对Cache写命中时,只修改Cache内容,而不立即写入主存,只有当此块被换出时才写回主存。因此每个Cache行必须设置一个标志位(脏位)用来确定Cache块是否被修改,是否需要写回主存。
    ②写不命中有两种处理方法:写分配法和非写分配法。当CPU对Cache写不命中时,把主存中的块调入Cache,在Cache中修改,通常搭配写回法。非写分配法当CPU对Cache写不命中时,不调入Cache,直接往主存中写入数据,通常搭配全写法。
  • Cache的换入换出和存储器的换入换出有什么区别?
    Cache的换入换出和存储区的换入换出主要集中在替换算法和写策略上。
    ①Cache的替换算法有随机算法、先进先出算法、最近最少使用算法、最不经常使用算法。
    ②存储区的替换算法有最佳置换算法、先进先出置换算法、最近最久未使用置换算法、时钟置换算法、改进型时钟置换算法。
    ③因为Cache需要和主存保持数据一致性,所以只有Cache有写策略。写策略分为写命中和写不命中。写命中有全写法和写回法。写不命中有写分配法和非写分配法。

高速缓冲存储器例题二

题目

例2 设某机内存容量为16MB,Cache的容量16KB,每块8个字,每个字32位.设计一个四路组相联映射(即Cache内每组包含4个字块)的Cache组织方式。
1)求满足组相联映射的主存地址字段中各字段的位数
2)设Cache的初态为空,CPU从主存第0号单元开始连续访问100个字(主存一次读出一个字),重复此次序读8次,求存储访问的命中率
3)若Cache的速度是主存速度的6倍,求存储系统访问加速比

解答

(1):
组相联映射主存地址被分成三个部分(由低位到高位):字快内地址、组地址、主存字块标记

  • 每一块容量8个字,每个字4个字节,包含32个字节,所以字块内地址需要5位。
  • Cache共有16KB/32B=512块,每组4块,得Cache共有512/4=128组。那么组地址就需要7位。
  • 16MB得主存容量需要24位地址。那么主存字块标记就是24-5-7=12位。

(2):
首先要明确一点:只有在第一遍访问时才会存在未命中情况,那么我们就需要计算第一次有多少个字没有命中。
当出现一次未命中时,主存就会把对应块上的数据传送到Cache中,那么我们只需要计算出第一遍遍历中主存向Cache传送了多少次数据,就可以得到未命中的次数。

100个字有100*4=400B,每一块存储空间为32B,那么100个字就需要400/32=13个块。
那么第一遍便利的时候主存需要向Cache传送13次数据,也就是说有13次未命中。
全部过程访问8*100=800次,未命中13次,则命中率为(800-13)/800=98.375%

(3):
设主存存取周期为6t,那么Cache存取周期就为t。
只有主存需要时间为:800*6t
加上缓存需要时间为:3*6t+787*t
加速比就为:(800*6t)/ (13*6t+787*t) = 5.549

以上是关于3-3存储系统-高速缓冲存储器Cache的主要内容,如果未能解决你的问题,请参考以下文章

Cache 简介

(计算机组成原理)第三章存储系统-第六节1:高速缓冲存储器Cache及其相关基本概念程序访问的局部性原理和命中率

高速缓冲存储器例题二

什么是Java缓存技术Cache

高速缓冲存储器Cache的局部性原理与性能分析

ARM体系结构简介