内存的类型:SRAM和DRAM
SRAM:基本电路单元是双稳态电路,6个晶体管实现,die面积大、成本高、;延时极小(门级延时),纯逻辑工艺方便集成到芯片内部。
DRAM:基本电路单元是单稳态电路,1个晶体管+1电容,die面积小、成本低;延时大,工艺复杂很难集成到芯片内存。
Cache要求访问速度快,所以Cache的存储单元通常是SRAM。
因为单位SRAM消耗的die面积较大,现在CPU L1/L2 Cache很难做得太大。Intel现在一般CPU L2 Cache是2MB?
问题:现在CPU顺便都是多少亿个晶体,2MB L2 Cache需要多少个晶体管呢?
介绍Cache的逻辑结构,以32KB L1 Cache为例、用图展示。
Total cache size = 32KB = 4-ways * 256-sets * 32Byte-cache_line
说明cache的寻址过程:
32bit address被分成Tag | Index | Offset三段。
使用Index选择4-sets(每way中选出一个set),4个选中的set中的Tag域与address中的Tag域比较。
如果有相等则cache命中,根据address中Offset域的从命中的cache line中取出数据给CPU。
否则cache不命中,需要从下一级cache或内存中调入数据
Cache的替换策略
LRU(Least Recently Used)、伪LRU
Random
WLRU - 王大师发明的,有兴趣的可以google下。
LRU实现需要额外的硬件实现。
结合TLB阐述Cache的寻找过程。在这里提到TLB是为了展示MIPS特有的Cache别名问题。
教科书中的寻址过程如下(仅讨论TLB和Cache都命中的情况):
虚拟地址 -> 访问TLB -> TLB命中 -> 物理地址 -> 访问Cache -> Cache命中 -> CPU取得数据
从CPU给出虚拟地址到CPU取得数据经过了好几步,商用CPU要求Cache命中时间在1~2 CPU clock内。
MIPS架构针对上述情况做了优化。
问题4:MIPS做了哪些优化,优化之后会导致什么问题?
答案在参考文献《See MIPS RUN》中
回顾:
Cache对于软件人员来说,大多数情况都是透明的。
但是平台有时候需要处理一些Cache不一致导致的问题,
因此了解Cache的原理,对写底层驱动和处理一些Cache不一致性的问题有帮助。
重点是:局部性原理、Cache逻辑结构、Cache一致性问题
摘抄自:MIPS架构培训之Cache原理
摘抄自:官方资料《ARM® Cortex™-A Series Version: 4.0 Programmer’s Guide》
其他相关资料:
Arm Architecture Reference Manual Armv8, for A-profile architecture
Arm® Architecture Reference Manual Supplement Armv9, for Armv9-A architecture profile
Arm Armv9-A A64 Instruction Set Architecture
摘抄自:ARM与MIPS的区别(转)
20220112学习
arm的mmu学习
ARM体系架构——MMU
所谓8路组相连( 8-way set associative)的含义是指,每个组里面有8个行。
我们知道,cache的容量要远远小于主存,主存和cache肯定不是一一对应的,那么主存中的地址和cache的映射关系是怎样的呢?
拿到一个地址,首先是映射到一个组里面去。如何映射?取内存地址的中间几位来映射。
举例来说,data cache: 32-KB, 8-way set associative, 64-byte line size
Cache总大小为32KB,8路组相连(每组有8个line),每个line的大小linesize为64Byte,OK,我们可以很轻易的算出一共有32K/8/64=64 个组。
对于32位的内存地址,每个line有2^6 = 64Byte,所以地址的【0,5】区分line中的那个字节。一共有64个组。我们取内存地址中间6为来hash查找地址属于那个组。即内存地址的【6,11】位来确定属于64组的哪一个组。组确定了之后,【12,31】的内存地址与组中8个line挨个比对,如果【12,31】为与某个line一致,并且这个line为有效,那么缓存命中。
OK,cache分成三类,
1 直接映射高速缓存,这个简单,即每个组只有一个line,选中组之后不需要和组中的每个line比对,因为只有一个line。
2 组相联高速缓存,这个就是我们前面介绍的cache。 S个组,每个组E个line。
3 全相联高速缓存,这个简单,只有一个组,就是全相联。不用hash来确定组,直接挨个比对高位地址,来确定是否命中。可以想见这种方式不适合大的缓存。想想看,如果4M 的大缓存 linesize为32Byte,采用全相联的话,就意味着410241024/32 = 128K 个line挨个比较,来确定是否命中,这是多要命的事情。高速缓存立马成了低速缓存了。
将此图与上图做对比,可以得出各参数如下:
B = 2^b
S = 2^s
现在来解释一下各个参数的意义:
一个cache被分为S个组,每个组有E个cacheline,而一个cacheline中,有B个存储单元,现代处理器中,这个存储单元一般是以字节(通常8个位)为单位的,也是最小的寻址单元。因此,在一个内存地址中,中间的s位决定了该单元被映射到哪一组,而最低的b位决定了该单元在cacheline中的偏移量。valid通常是一位,代表该cacheline是否是有效的(当该cacheline不存在内存映射时,当然是无效的)。tag就是内存地址的高t位,因为可能会有多个内存地址映射到同一个cacheline中,所以该位是用来校验该cacheline是否是CPU要访问的内存单元。
当tag和valid校验成功是,我们称为cache命中,这时只要将cache中的单元取出,放入CPU寄存器中即可。
当tag或valid校验失败的时候,就说明要访问的内存单元(也可能是连续的一些单元,如int占4个字节,double占8个字节)并不在cache中,这时就需要去内存中取了,这就是cache不命中的情况(cache miss)。当不命中的情况发生时,系统就会从内存中取得该单元,将其装入cache中,与此同时也放入CPU寄存器中,等待下一步处理。注意,以下这一点对理解linux cache机制非常重要:
摘抄自:计算机缓存Cache以及Cache Line详解