计算机组成原理自学笔记——Cache

内容概述:

  • 基本概念
  • 原理
  • 和主存的映射方式
  • 替换算法
  • 写策略


1.基本概念

其他存储器相较于CPU的速度差距很大

设计更高速的存储单元

Cache通常被集成在CPU内部

用SRAM实现,成本高,但是速度快

要考虑到集成度的原因,Cache不能做的很大,所以空间较小

2.原理

辅存→内存→Cache→CPU

内存中的存放此时运行的程序

但是大部分指令都不会频繁的使用

所以要将频繁使用的一些指令代码复制到Cache里面

让CPU直接在Cache里面取指令和数据

CPU和内存直接的速度差距矛盾就会被缓和

局部性原理(适用于指令和数据)

空间局部性

最近的未来要用到的信息,很可能与现在使用的信息存储空间上是相邻的

eg. 数组元素,顺序执行的指令代码

时间局部性

在最近的未来要用到的信息,很可能是现在正在使用的信息

eg.循环结构的指令代码

基于局部性原理,得出结论

可以把CPU目前访问的地址 周围 的部分数据放入Cache中

如何界定周围:

将主存的存储空间 分块

主存和Cache之间以“块”为单位进行数据交换

每次被访问的主存块,一定会被立即调入Cache

操作系统中,通常将主存里面的一个块,称为一个页

块也可以称为行

主存的地址一共22位

块号 12位   块内地址  10位

所以依据原理,访问二维数组时,行优先相较于列优先,空间局部性差,速度慢

性能分析

如果CPU想要的数据能够直接在Cache中找到

我们称为  命中

命中率H:CPU欲访问的信息已在Cache中的比率

缺失(未命中)率 M = 1-H

假设CPU访问Cache耗时tc

访问主存耗时tm

由于CPU每次都会优先访问Cache

如果Cache未命中,才会去访问主存

平均访问时间=

H tc + (1-H)(tc + tm)

如果同时访问主存和Cache

如果Cache命中了则立刻停止访问主存

平均访问时间=

H tc + (1-H)tm

3.和主存的映射方式

如何区分Cache与主存的数据块的对应关系

Cache有标记位 和 有效位

标记位: 初始置零,主存有存入后,修改为主存的标号(位数与主存块号一致)

有效位: 放入之后从0变为1

主存地址:  主存块号+块内地址

全相联映射

主存块可以放在Cache的任意位置

Cache行(Cache块)与主存块大小相等

CPU访问主存地址的过程

  • 访问主存地址的前几位(主存块号),对比Cache所有块的标记
  • 如果标记匹配,且有效位为1,则Cache命中,接着访问块内地址
  • 未命中,则正常访问主存

直接映射

每个主存块只能放到一个特定的位置

Cache块号 = 主存块号 % Cache总块数 

缺点:Cache的其他位置虽然有空闲位置,但是不可以使用,只能传到固定位置

例如,Cache如果有8个行

           判断主存中第0块,0%8=0,放到Cache的第0行

           第8块,8%8=0,则覆盖第0行的数据,并修改标记

如果Cache的总块数=2的n次幂,

则主存块号末尾的n位(二进制)就直接反映了他在Cache中的位置

则可以优化标记,存储主存块号的其余位作为标记即可

主存块号=标记+行号

CPU访问主存地址的过程

  • 根据主存块号的后n位确定Cache行
  • 若主存块号的前几位和标记匹配,且有效位为1,则命中,访问存储单元
  • 若未命中,则正常直接访问主存

组相联映射

Cache块分为若干组,每个主存块可以放到特定分组中的任意一个位置

组号 = 主存号 % 分组数

常见分法:二路组相联 即两个块为一组

例如,Cache一共有8个行,则分组数为4

           优化标记:4=2的2次幂,相当于只看最后两位即可判断是哪一组的

                             标记位可以不标记最后两位

                              主存块号=标记+组号

CPU访问主存地址的过程

  • 根据主存块号的后几位,确定所属的分组号
  • 再判断前几位对比标记,如果匹配且有效位=1,则Cache命中,访问块内地址d
  • 若未命中,则正常直接访问主存

4.替换算法

Cache很小,内存很大,如果Cache满了怎么办

全相联映射:Cache完全满了才需要替换,需要在全局选择呢替换哪一块

直接映射:对应位置非空,则可以直接替换,无需考虑替换算法

组相联映射:分组内满了才需要替换,需要在分组内选择替换哪一块

随机算法 RAND

顾名思义,随机选择一块进行替换,完全没有考虑局部性原理,命中率低,效果不稳定

先进先出算法 FIFO

替换最先被调入Cache的块,实现简单,依然没有考虑局部性原理

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

近期最少使用 LRU

为每一个Cache块都设置计数器,用于记录这个块多久没有被访问到了,替换时,优先替换计数器最大的一个块

原理:

1.命中时,命中的行的计数器清零,比其计数器值低的计数器加1,其余不变

               因为已经很大的数,没必要再浪费资源+1

2.未命中且有空闲行时,装入新的行,计数器置0,其他空闲行+1

3.未命中且没有空闲行,计数器最大的行信息块被替换,新装入的块计数器置0,其余加1

Cache块的总数=2的n次幂,则计数器需要n位即可

且Cache装满了,计数器的值一定不重复 

基于局部性原理,近期被访问过的主存块,在将来也会被再次访问

淘汰最久没有被访问的块是合理的

运行效果很好,Cache命中率高

但是如果频繁访问的主存块数量>Cache行的数量,则可能会发生抖动

最近不经常使用 LFU

为每一个Cache块都设置计数器,用于记录每一个Cache被访问过几次,然后替换计数器最小的

原理:

新调入的计数器置零,每次被访问一次计数器就+1,需要替换时选择计数器最小的一行

若有多个最小,则可以按行号递增顺序或者FIFO策略进行选择

曾经被访问的主存块在未来不一定能用到,但是并没有很好的遵循局部性原理,实际运行效果不如LRU

5.写策略

CPU修改了Cache中的数据副本,怎么样保证与主存中的数据母本的一致性

写命中

  • 全写法

写直通法,当CPU对Cache写命中时,必须要将数据同时写入Cache和主存

访存次数增加,速度变慢,但是能保证数据的一致性

写缓冲:用SRAM实现的FIFO队列,先写到写缓冲中,要比直接写到内存里面要块

               再利用专门的控制电路逐一写回

               淘汰Cache中的内容时,也不需要写回

CPU的速度很快,若写操作不频繁,效果很好,频繁的话,可能会因为写缓冲饱和而发生阻塞

  • 写回法

当CPU对Cache写命中时,只修改Cache的内容,而不立即写入内存,只有在当此块被换出再写入内存

未被修改过的块,不必写回

在Cache中添加一个脏位,表示是否被修改过,初始全部置零,修改后,该行置1

减少了访存次数,但是存在数据不一致的隐患

写不命中

  • 写分配法

当CPU对Cache没有命中,则把主存对应的整块调入Cache中,在Cache中修改,通常搭配写回法使用

即,如果未命中,正常调入Cache再利用写回法进行后续的修改操作

  • 非写分配法

当CPU对Cache没有命中,则只写入内存,不调入Cache,搭配全写法

这样的情况,只有读未命中,才会将内存的数据调入Cache

多级Cache

离CPU越近,速度越快,容量越小

各级Cache之间,采用 全写法+非写分配法

Cache与主存之间,采用 写回法+写分配法

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值