Cache是指位于CPU和主存之间的一个高速小容量的存储器,一般由SRAM构成。
目录
Cache 的作用及实现提高访存速度的原理
cache/主存访问时间
主存块在不同映射方式下,主存地址格式的计算
全相联映射
例子
直接映射
例子
组相联映射
例子:
总结:
Cache功能:用于弥补CPU和主存之间的速度差异, 提高CPU访问主存的平均速度。
例题
CPU执行一段时间时,Cache完成存取的次数为3900次,主存完成的存取次数为100次,已知cache的存储周期为40ns,主存的存储周期为240ns。求cache/主存系统的效率和平均访问时间?
(PS(错误修正!):97.5%+40ns改为97.5%*40ns
0.25%改为2.5%
)
Cache的数据块称为行,主存的数据块称为块,行与块是等长的;
主存容量为2^m块,Cache容量为2^c行,每个字块中含2^b字。最重要的是单位要化到统一才能计算
地址映射:根据主存地址,判断访问字所处的块, 是否在cache某行中,决定一次CPU的访存是否命中 Cache。本质上是对主存的地址进行“解析” .
主存与地址映射的方式与三种
特点:是多对多的映射关系:对于主存的任何一块均可以映射到Cache的任何一行,主存块的编号是唯一的。
映射过程:
1)主存方向看,一个主存块可以映射到任意一个空的行上;
2)Cache方向看,一个行上可以存放任意一个主存块;
优点:机制灵活,命中率高。
缺点:比较器电路难于设计和实现,因此只适合于小容量的Cache。
(1)行与块等大小,主存的任意块可以映射到cache的任意行,直到cache所有的行放满为止; (2)主存的地址分为2部分:块号+字。块号是主存各个块的标志(tag),块号的编码长度由主存的块数决定; 就比如求cache中多少个行,如果是全相联的话,就cache大小/每一块的大小
每一块有16个单元,则块内地址2^4=16,为4为;
主存块号 | 块内地址 |
(3)放入cache缓存的块,其块号与块的内容一起被拷贝 到cache某一行中;
(4)在cache中,全部标志tag使用相联存储器实现,全部数据使用SRAM实现;
在每一行中,因为要节约大小,不可能每一个行中都只放主存中一个地址,这样太浪费空间了
,所以就有全相联的方式 。例如每一块有4个单元,主存地址总线为16位,则:
每一块的地址tag | 每一块四个单元的数据总和 |
(5)块冲突率低, cache利用率高,判决速度慢。比较器难以设计,只适合小容量cache使用。
相对于直接映射来说,比较器太难设计了
区别于全相联映射,直接映射是把一个主存块只能映射到cache中的唯一行上。主存的块按cache的行数循环编号,相同的块号映射到cache中相同的行位置上。主存块号不唯一。
这么做的方式就是减少比较器的设计,不用一个个比对,更容易找到所在的主存映射到cache的块
我的理解:就是在全相联的基础上把每一个块按规定摆放,这样子就在全相联的结构中的tag再分出行号(tag变小了。。),通过这个主存块上的行号,规定每一个主存块只能放到它所固定的行上。
主存字块标记(tag)S | cache行号( r ) | 字块内地址(块内地址)W |
特点:
地址变换速度快,块冲突率高,适合于大容量cache的场合,通过增加行数来减少冲突概率。
主存地址格式: tag(大组号)、行(块)号、块内字地址
主存地址:S+W位——2^S块、块内2^W个字,Cache的行数=2^r 标记tag=S-r
例题二:主存容量为512KB,Cache容量为4KB,每个字块为16个字,每个字32位。
1)Cache地址有多少位,可容纳多少块?
2)主存地址有多少位,可容纳多少块?
3)在直接方式下,主存的哪些块可映射到Cache中的第5行?
4)画出直接映射方式下主存地址字段中各段的位数。
5)全相联映射方式下的主存块B971,直接映射方式下,可以调入到Cache的哪一行?
解:
1)Cache容量4KB,2^12=4KB,地址位数为12位,由于每个字32位(题目有讲) , 所以每个字32位/8=4字节(B)【由一个字节为8位可知】
Cache有4KB/4B=1K字 ,每个字块有16个字(题设,所以块内地址位数为4),故 Cache有1K/16=64=2^6行(行地址位数为6位);
2)主存容量512KB(2^19),主存有512KB/4B(32位)=128K 个字,有128K/16(题设1块16字)=8192=2^13块;每块有16=2^4个字 =2^6B(字节)【一个字32/8=4B】;
3)直接映射下,Cache有64行,主存有8192块,主存 的第4、64+4、2*64+4、……(2^7-1)*64+4能够映 射到Cache的第5行(行号L4,即000100);
4)字块内地址6位(字节),Cache字块地址6位,主存字块标记地址=19-12=7位,或者是 13-6=7位
主存字块标记(7) | Cache 行地址(6) | 字块内地址(6) |
5)方法1:把B971块号转换为二进制数, 确定出tag和行地址编码,计算十进制的行号
方法2:用971除以2^6=64(Cache的行数),求出商和余数的二进制数
映射的Cache行号=余数=主存地址格式中的行(块)号 tag=0001111,映射到Cache的L11行上
组相联映射是集合了上面两种的优点,也是现在设备中最常用的方式
我的理解:就是基于直接映射里面的每一行变成每一个组,然后每一个组里面不像直接映射一样只能放一个块,而是可以放n个块,然后在每一个组里面运用全相联映射模式去寻找数据
怎么说,这个组相联的方式更像是保存上一次存入同样组号的数据块,就极大地避免了直接相连命中率低的情况。。
做习题的时候要注意的是,我们已经获取了cache有多少行,但是我们要把
cache的总行数/cache每一组的行数=cache的组数,其他的tag与块内地址与直接映射大同小异
X路组相联就相当于一组X行。
主存字块标记(tag)S | cache组号( d ) | 字块内地址(块内地址)W |
例题5.假设主存容量为512K*16位, Cache容量为4096*16位,块长为4个16 位的字,访存地址为字地址。
1)在直接映射下,设计主存的地址格式
2)在全相联方式下,设计主存地址格式
3)在二路组相联映射方式下,设计主存 地址格式
4)若主存容量、Cache容量、块长不变, 在四路组相联方式下,设计主存地址格式
解:
主存块=4个字=2^2个字(题设,按字编址噢),块内字地址2位
主存容量=512K个字=(512K*16位)/(4*16位[每个块的容量])= 2^17个块
(害,这时候别耍小聪明,不要把每一个块化为具体KB大小。。)
Cache容量=4096个字=(4096*16)/(4*16)= 2^10行
直接映射下,主存的块号编码=Cache行号编码 =10位,主存各个块标记Tag= 17-10=7位
主存地址格式:
Tag(7位) | 行号(10位) | 块内字(2位) |
全相联方式:Tag=主存块号编码=17位
Tag(17位) | 块内字(2位) |
2路组相联:
Cache组数= 2^10/2= 2^9组,主存块号编码 =Cache组数编码=9位,Tag=17-9=8位
Tag(8位) | 组号(9位) | 块内字(2位) |
4路组相联: Cache组数= 2^10/4= 2^8组,主存块号编码 =Cache组数编码=8位,Tag=17-8=9位
Tag(9位) | 组号(8位) | 块内字(2位) |
例二:
设主存容量为16MB,Cache容量为8KB,每字块有8个字,每个字32位, 设计一个4路组相联映射的Cache组织。 访存地址为字地址。
解:
主存块=8个字=2^3个字,块内字地址3位(块内地址不是多少个字节喔。因为是按字编址)
主存容量=16MB=4M个字(一个字32位/8=4字节(B))=4M/8(每个块8个字)= 2^19个块
Cache容量=8KB=2K个字(一个字32位/8=4字节(B))=2K/8= 2^8行
4路组相联下,Cache组数= 2^8/4= 2^6组
主存块号编码=Cache组号编码=6位,主存各个块标记Tag= 19-6=13位 主存地址格式:
Tag(13位) | 组号(6位) | 块内字(3位) |
上面的例题要搞清楚是按字节编址还是按字编址
求cache的行数应该要转成相同的单位与块相同的单位才能求出,主存也一个样,化繁为简
,按字就按字整除,字节就按字节,位数就按位数整除。。
有些时候多少块(数量级无单位)【针对主存有多少个块,此时要区分块内地址,全相联映射只考虑多少个块】
多少行(数量级无单位)【针对cache中有多少行,直接映射会用到】
多少组(数量级无单位)【针对cache分组后有多少个组,一般是行/(一组多少行),组相联映射】
作业:
更新:发现老师的做法和我这篇博客的字节编址出入很大,还是按照老师的想法吧。。。
按字节编址的话,就是把我上面的那个博客里面字节编址的块内地址分出两块
块内字地址(一个块多少个字) | 字内字节地址(一个字多少字节) |
(
组相联映射:如果说是按主存的字节地址格式,出现了一个字块有多少个字,则写出字段时,分出多一块写一个字的多少个字节进行编码地址。。
直接映射:如果说只告诉了一个块多少字节,但是没有说一个块内有多少个字,就按字节编址
)
作业2: