快速连接
👉👉👉【精选】ARMv8/ARMv9架构入门到精通-目录 👈👈👈
1. cache的查询原理
高速缓存控制器(cache controller )是负责管理高速缓存内存的硬件块,其方式对程序来说在很大程度上是不可见的。它自动将代码或数据从主存写入缓存。它从core接收读取和写入内存请求,并对高速缓存或外部存储器执行必要的操作。
当它收到来自core的请求时,它必须检查是否能在缓存中找到所请求的地址。这称为缓存查找(cache look-up)。它通过将请求的地址位的subset(index)与与缓存中的physical TAG 进行比较来做到这一点。如果存在匹配,称为命中(hit),并且该行被标记为有效,则使用高速缓存进行读取或写入。
当core从特定地址请求指令或数据,但与缓存标签不匹配或标签无效时,会导致缓存未命中,请求必须传递到内存层次结构的下一层,即 L2缓存或外部存储器。它还可能导致缓存行填充。缓存行填充会导致将一块主内存的内容复制到缓存中。同时,请求的数据或指令被流式传输到core。这个过程软件开发人员不能直接看到。在使用数据之前,core不需要等待 linefill 完成。高速缓存控制器通常首先访问高速缓存行内的关键字。例如,如果您执行的加载指令在缓存中未命中并触发缓存行填充,则内核首先检索缓存行中包含所请求数据的那部分。这些关键数据被提供给core流水线,而缓存硬件和外部总线接口随后在后台读取缓存线的其余部分。
总结一下就是:先使用index去查询cache,然后再比较TAG,比较TAG之后再检查valid标志位。
但是这里要注意:TAG包含了不仅仅是物理地址,还有很多其它的东西,如NS比特位等,这些都是在比较TAG的时候完成。
2. cache的查询示例
假设一个4路相连的cache(如cortex-A710),大小64KB, cache line = 64bytes,那么 1 way = 16KB,indexs = 16KB / 64bytes = 256 (注: 0x4000 = 16KB、0x40 = 64 bytes)
0x**4000 -- index 0
0x**4040 -- index 1
0x**4080 -- index 2
......
0x**7fc0 -- index 2550x**8000 -- index 0
0x**8040 -- index 1
0x**8080 -- index 2
......
0x**bfc0 -- index 255
细心的同学可以发现,这里就有了一个很大的问题,你用于cache look-up的index是vaddr[15:6], 如果granue size是4KB,那么vaddr[11:0] = paddrr[11:0] , 但是vaddr[15:12]比特并不等于paddrr[15:12] ,那么你这样的index查询的cache有效吗?会不会发生同名、歧义 ?
关注"Arm精选"公众号,备注进ARM交流讨论区。