2024.06.08:计算机组成原理学习笔记
第10节 cache
10.1 局部性原理
cache建立的基础
局部性原理实际上是告诉我们这样一个事实:有一些元素或者说变量在短时间内是会被重复访问、高频次访问,或者说两个相邻的元素或者变量在短时间内会被连续访问的。
10.1.1 时间局部性
被访问的某一个存储单元在一个较短的时间间隔内很可能又被访问。
10.1.2 空间局部性
- 被访问的某个存储单元的物理上邻近单元在一个较短的时间间隔内很可能也被访问。
- 空间局部性是指物理上相邻的两个单元在短时间内被访问
- 空间局部性对与单个变量是没有意义的,空间局部性强调的是物理上相邻的两个对象。
- 如果访问顺序和存放顺序一致,那么它的空间局部性是好的
10.2 cache的工作原理
10.2.1 cache地址与主存地址
- 常用的数据/指令总是占用多个存储单元,因此应以多个存储单元为单位将信息复制到高速缓冲存储器cache中。
注意:我们去复制cache的时候,不是以一个存储单元为单位的
cache的设计重点:常用的数据/指令总是占用多个存储单元,因此应根据情况划分主存块,一个主存块中包含多个存储单元,主存块作为主存和cache之间交换的单位。
块的思想:在存储器的不同层次的设备之间,如果需要进行数据交换,我们会引入一个块单位,并且我们还要解决这两个层次之间映射的问题
- 将主存中经常访问的主存块复制到cache中
cache会被分为n个块,我们把它叫做行
- cache中存放着主存中被频繁访问的程序和数据,以便CPU直接访问
- 由于cache只有主存中部分程序和数据的副本,因此cache容量远远小于主存
(1) cache地址

- 当一串二进制的码作为地址出现。
注意:地址永远都是用来标记存储单元的,每一个存储单元都会有一个地址,存储单元就是编址的单位 - 我们可以把高位看成cache地址的行号,低位看成cache的块内地址
(2) 主存地址
由于主存地址的分析过程与cache地址一模一样,略

(3) cache地址与主存地址
cache中间的每一个行都是由主存块复制过来的,这两个大小是完全一样的,所以,一个cache行或者一个主存块内,存储单元的个数是一定相等的。

因此,cache地址和主存地址的低位的块内地址,实际上是同一个东西,他们都在指示这样的一个单位块里面由多少个存储单元,而你的cache行又是从主存块当中复制过去的,所以他们是完全相同的
XX地址:这个XX地址只能用来锁定一个存储单元,而XX地址就代表它在XX东西里面去找这个存储单元。
408考研题不太常见cache地址,一般都是用一个主存地址去访存,但是如何用一个主存地址去访问cache呢,这也就是我们后面要学习的映射方式所要解决的问题
10.2.2 cache的有效位
cache有效位的提出是为了说明cache行中的信息是否有效,因此,每一个cache行都需要一个有效位。

- 系统启动/复位时,每个cache行都为空,其中信息无效,只有装入了主存块后信息才有效。
- 装入了主存块信息后,cache行的有效位会变成1
- 如果想要淘汰某个cache行中的主存块信息,可以修改有效位为0,实现冲刷
虽然物理上并没有删除这些信息,但是有效位==0可以让这些信息全部失效
- 有效位是cache行中专门设置的位,主存块中没有
题干如果提到cache数据区的容量是多少,也就是告诉你主存块的容量有多大
10.2.3 CPU在cache中的访问过程*
CPU访问cache是为了取数据,数据存放在cache里面的存储单元,存储单元的地址在cache里面是由cache地址来标志的,但是CPU在访问cache的时候,是不会用到cache的地址而是在用主存地址
思考:为什么CPU访问cache的时候,不用cache地址,而去使用主存地址?

(1) cache命中
- 若CPU访问单元所在块在cache中,则称cache命中
- 命中的概率称为命中率,它等于命中次数和访问总次数之比
(2) cache缺失处理(缺失代价)

10.2.4 cache-主存的平均访问时间(看大黑书理解)
命中时,CPU在cache中直接存取信息所用的时间开销是cache访问时间T,其中包括了判断当前访问时命中还是缺失的时间
命中时,执行一次cache读
- 命中时,CPU在cache中直接存取信息,所用的时间开销是cache访问时间Tc
不命中时,执行一次cache读+缺失代价
- 未命中时,需要从主存读取一个主存块送cache,并同时将所需信息送CPU。总时间开销为缺失代价Tm和cache访问时间Tc之和

- CPU在cache-主存的平均访问时间:
10.3 cache行和主存块之间的映射关系*
思考:CPU是通过主存地址去访问cache的,但是主存地址我们的划分又是主存块号和块内地址,那它是怎么根据这样一个地址,得出它映射到cache的哪一块呢?
主存地址中就包含了cache地址,而且我们一般不用“cache地址”这个词语,而是直接根据cache的映射方式解析主存地址的结构。只要知道主存地址+cache映射方式+cache总行数 就自然知道在哪一个cache行里了
将主存块复制到cache行时,主存块和cache行之间必须遵循一定的规则,这样在CPU访问某个主存单元时,可以根据映射规则到cache所对应的行中查找要访问的信息,而不用在整个cache中遍历查找
10.3.1 直接映射*
每个主存块映射到cache的固定行中
cache行号==主存块号 mod cache 行数(记得换成十进制计算)
主存块和cache行完全一致,存储单元的个数一致,因此块内地址完全相同

注意:cache行号占中间的C位是通过观察映射公式总结规律发现的
- 直接映射可以通过公式算出某一个主存地址它会映射到哪一行去,我们只需要去拿主存地址高位的主存块号,把它换成十进制,然后对cache总共的行数取余就可以了
思考:如何根据一个主存地址,知道映射到cache的哪一行呢
- 当你把主存地址和cache地址对齐后,前面插了一个(m-c)位,而后b位又是完全相同的,所以cache行号的这个c位,它实际上就是主存块号的低c位
- 给每个cache行设置一个t=m-c位长的标记tag,主存某块调入cache之后,就将主存地址高t位设置在cache行的标记位中
注意理解:
- tag位会同时出现在cache行内以及主存地址中
- 但是块内地址、cache行号是地址的划分,不会出现在cache行中

- CPU给出主存地址
- 根据主存地址中间的c位找到对应的cache行
- 对比cache行和主存地址的tag位,并观察cache行的有效位,若为,则访问cache命中
- CPU从主存读出该地址所在的一整块信息送到对应的cache行,并设置有效位为1,tag位设置为高t位,同时将该地址中的内容送至CPU
- 【注】cache缺失的时候,我们可能会从主存直接将数据读取至CPU,具体看题目要求
cache题目解题思路:1.根据映射方式确定地址划分 2.根据题目条件确定地址每个部分的位数 3.区分题目求的是地址还是cache行的内容
tag位数
- 主存大小除以cache大小,再取一个对数
- tag位数其实就是为了记录你的主存可以往cache里面放满多少轮
- 地址映射表== 标记阵列 ==(tag位+有效位+一致性维护位+替换算法位)
10.3.2 全相联映射
每个主存块映射到cache的任意行中

- 给每个cache行设置一个m位长的标记tag
- 主存某块调入cache之后
- 就将主存地址高t位设置在cache行的标记位中
10.3.3 组相连映射*
组相联映射很像是直接映射和全相联映射的一个综合
每个主存块映射到cache固定组的任意行中
cache组号==主存块号 mod cache 行数

10.3.4 映射总结
(1) 关联度
- 关联度:一个主存块映射到cache中时可能存放的位置个数
- 关联度越低,命中率越低,因此直接映射命中率最低,全相联映射命中率最高
- 关联度越低,判断是否命中的开销越小,命中时间越短,因此直接映射的命中时间最短,全相联映射命中时间最长
-
- 直接映射关联度:1
-
- 全相联映射关联度:cache行数
-
- 组相连映射关联度:组路数
(2) 比较器
- 比较器位数等于tag位数,用于对比tag
- 法则:当地址无法精确到cache行时,需要用到比较器
- 比较器是cache里面自带的一个器件
-
- 直接映射:比较器个数:1;比较器位数:tag
-
- 全相联映射:比较器个数:cache行数;比较器位数:tag
-
- 组相联映射:比较器个数:组路数;比较器位数:tag
10.4 cache中的主存块的替换方式*
我们想要淘汰cache行中某一行的信息,让一个新的主存块装进来,cache行有效位置0就可以了,但是具体过程是怎么样呢,怎样决定淘汰哪一个块呢?
- cache行数比主存块数少得多,往往出现多个主存块映射到同一个cache行中
- 当一个新的主存块复制到cache时,cache中的对应行可能已经被全部占满,必须淘宝一个cache行中的主存块,才能继续装入
10.4.1 先进先出算法FIFO
总是选择最早装入cache的主存块被替换
10.4.2 最近最少用算法LRU(重点理解 )
- 总是选择近期最少使用的主存块被替换
- LRU计数器(LRU位、替换算法位)

计数器的值越高,就代表行中的主存块是最近最少使用的
-
- 1.命中时,被访问的行的计数器清零,比其低的计数器加1,其余不变
-
- 2.未命中且该组还有空闲行时,则新装入的行的计数器设为0,其余全加1
-
- 3.未命中且该组无空闲行时,计数值为2的那一行中的主存块被淘汰,新装入的行的计数器设为0,其余加1
10.4.3 最不常用算法LFU
替换cache中引用次数最少的块
10.4.4 随机替换算法
从候选行中随机选取一个淘汰
10.5 cache的一致性问题
把一个主存块复制到了cache中,并且在cache中,对这个主存块的某一个存储单元进行了改写,也就是写操作。
cache中的内容是主存块副本,当对cache中的内容进行更新时,就存在cache和主存如何保持一致的问题
注意:
- 回写法一般搭配写分配法进行使用
- 全写法随意搭配
10.5.1 写命中
要改写的主存块中的存储单元,已经复制进入cache中
(1) 全写法
如果写命中,则同时写cache和主存
(2) 回写法(cache中只有回写法有一致性控制位)
若写命中,则信息只被写入cache而不被写入主存,只有当此块被替换出时才写回主存

对于每个cache行设置一个一致性维护位(修改位、脏位),若修改位为1,说明对应cache行中的主存块被修改过,替换时需要写回主存
10.5.2 写不命中
要改写的主存块中的存储单元不在cache中
(1) 写分配法
先在主存块中更新相应的存储单元,然后分配一个空闲的cache行,将更新后的主存块装入到分配的cache行中
(2) 非写分配法
仅更新主存单元而不装入主存块到cache中

627

被折叠的 条评论
为什么被折叠?



