前面两天学习了一下Linux的内存相关的东西,但是学习内存,那必然要学习一下缓存。cache这个玩意可是老有名气了。
前面也在学习的时候看到了几个关于cache的名词,先放在前面。中间学习的时候忘了就回头看,不断的重复就熟悉了。
1、名词表-VIVT、VIPT、PIPT
其中几个关键名词:
1、VIVT-虚拟高速缓存 VIVT(Virtually-Indexed Virtually-Tagged)
**虚拟高速缓存以虚拟地址作为查找对象**,即虚拟地址做 index,虚拟地址做 Tag,在查找 Cache line 过程中不借助物理地址,在 ARM 初期的 ARM4、ARM5 等处理器的 Cache 主要采用这种方式。
虚拟高速缓存(VIVT)以**虚拟地址(VA)**作为查找对象,当CPU发出虚拟地址时,Cache 根据送来的虚拟地址中的 index 部分在 Cache中查找对应的 Cache line,将查找的 Cache line 对应的 Tag 部分与虚拟地址(VA)的 Tag 部分进行比较,若 Tag 部分相同,则命中。
之后根据Cache line中的有效位(valid)确定 Cache line 中的数据是否有效,有效则根据虚拟地址中的 Offset 部分找到对应的数据,将其返回给 CPU。若在比较 Tag 过程中发现不对应,则发生 Cache miss,此时需要将虚拟地址通过 MMU 转为物理地址后根据物理地址找到对应的主存数据存放地址,将数据返回给 CPU 和 Cache。
优点
CPU在进行读取或写入操作时,不需要每次都将虚拟地址通过 MMU 转为物理地址,这大大节省了 CPU 等待的时间。同时由于不需要进行虚拟地址转物理地址,所以硬件设计也相对更加简单。
缺点
当然 VIVT 也有它的不足,在进行数据查找过程中,由于使用虚拟地址作为 Tag,所以引入两个问题。 歧义(ambiguity) 和 别名(alias) 。为了保证系统的正确工作,可以使用操作系统来避免出现歧义和别名两个问题。
2. VIPT-物理标记的虚拟高速缓存 VIPT(Virtually-Indexed Physically-Tagged)
在使用虚拟存储器的系统中,物理标记的虚拟高速缓存VIPT 使用虚拟地址做 index ,物理地址做 Tag。 在利用虚拟地址索引 Cache 的同时利用 TLB/MMU 将虚拟地址转换为物理地址**。然后将转换后的物理地址与虚拟地址索引到的 Cache line 中的 Tag 作比较,如果匹配则命中**。这种方式要比 VIVT 实现复杂,在进行进程切换时,不在需要对 Cache 进行 invalidate 等操作(因为匹配过程中需要借物理地址)。但是这种方法仍然存在 Cache 别名(Alias)的问题(即两个不同的虚拟地址映射到同一物理地址,且位于不同的 Cache line)。
物理标记的虚拟高速缓存(VIVT)以物理地址部分位作为 Tag ,使用虚拟地址 index 进行 Cache line 的索引。
当 CPU 发出虚拟地址(VA)时,根据虚拟地址的 index 进行 Cache line 的查找,同时,内存管理单元(MMU)将虚拟地址(VA)转为物理地址(PA),当地址转换完成,同时 Cache 控制器也对 Cache line 查找完成,此时将查找到的 Cache line 对应的 Tag 和物理地址 Tag 域进行比较,以判断 Cache 是否命中。
3. PIPT-物理高速缓存 PIPT(Physically-Indexed,Physically-Tagged)
在使用虚拟存储器的系统中,物理高速缓存 PIPT 中的 Tag 和 index 均为物理地址,而 CPU 发出的是虚拟地址,这便需要通过 TLB/MMU 查询内存中的页表,先将 CPU 发出的虚拟地址转换为物理地址,再进行 Cache 的缓存查找,这种先将 CPU 发出的虚拟地址转为物理地址,之后将物理地址作为访问 Cache 的 Tag 和 index 的方式称为 PIPT(Physically-Indexed,Physically-Tagged)。
ARM 的 Cortex-A 系列高性能处理器大多采用 PIPT 方式,PIPT 的方式在芯片的设计要比 VIPT 复杂很多,而且需要等待 TLB/MMU 将虚拟地址转换为物理地址后,才能进行 Cache line 寻找操作,所以相对的速度相较于 VIPT 慢。
由于寻址 TLB 的过程也需要消耗一定的时间,对处理器的周期时间会造成一定的影响,所以一些处理器将访问 TLB 的过程单独作为一个流水线,用以减少访问 TLB 对处理器周期时间的影响。
物理高速缓存 PIPT使用物理地址做 Tag 和 index 。首先CPU 发出的虚拟地址经过 MMU 转换成物理地址,之后将物理地址发往 Cache 控制器,通过物理地址中的 index 部分对 Cache line 进行查找,查找到对应 Cache line 后将物理地址的 Tag 部分与 Cache line 中的 Tag 部分进行比较,如果相同,则命中,之后根据有效位(valid)进一步确定是否直接返回给 CPU,如果 Tag 部分不相同,则将内存中对应地址的数据取出返回给 CPU 和 Cache。
三者的区别其实就是里面保存内容的区别。
(PIVT是一种比较奇葩的设计,只有MIPS R6000芯片采用了这种设计,并且很快被市场淘汰,可见这个设计并不是很成功,讨论度不高。)
感谢前辈的优秀文章