这是图解系列之CPU cache
本文接着说Cache的歧义别名
关注阅读更多图解
对内存管理还不太清楚,可以先看我之前关于MMU的文章。
对Cache基本原理不太清楚,可以先看我之前的Cache基本原理。
在《图解 | CPU-Cache》一文中介绍了VIVT、PIPT、VIPT三种查找方式。下面分析一下其歧义别名问题。
歧义:查找到的Cacheline先后指向多个物理地址。
别名:一个物理地址被加载到不同的Cacheline中。
VIVT
歧义:VIVT时,相同的虚拟地址映射不同的物理地址就会出现歧义。
VIVT歧义举例:两个进程的某一相同虚拟机地址指向了不同的物理地址,进程A运行时CPU把此虚拟地址加载到了Cacheline中,进程B运行时,CPU在Cache中查找此地址时会发现Cache hit,从而加载了错误的物理地址内存。
操作系统为了避免VIVT歧义,在进程切换时,可以flush所有的cache,使主存储器有效,高速缓存无效。后果就是切换后的进程会有大量的cache miss导致性能损失。
别名:基于VIVT,在2个虚拟地址对应同一个物理地址时,对于index和tag,2个虚拟地址都是可能不同的,它们完全可能在2个Cacheline同时命中。此时就出现了别名问题。
VIVT Cache由于问题多难管理。所以现在CPU已经不使用这种方式。现在CPU使用PIPT或者VIPT。
PIPT
歧义:PIPT时,同时index和tag都是基于物理地址,也不存在查到多个Cacheline对应一个物理地址,所以不存在歧义问题。
别名:基于PIPT,在2个虚拟地址对应同一个物理地址时,由于物理地址一样,基于此物理地址去查找和比对Cache,是不会查到两个Cacheline的,所以PIPT不存在别名问题。
PIPT即不存在歧义也不存在别名。现在CPU大多采用PIPT高速缓存设计。在Linux内核中PIPT高速缓存的管理函数都是空函数,无需管理。
VIPT
歧义:VIPT以物理地址部分位作为tag,因此不会存在歧义问题。
VIPT的别名问题分几种情况来看:
首先是下图所示的,index+offset的长度小于一个page的长度,即cache的size除以WAY数小于1个page的大小时,此时VI等于PI,所以没有别名问题。(为什么?因为此时VIPT就是PIPT了)
其次是下图所示的,index+offset的长度等于一个page的长度,即cache的size除以WAY数等于1个page的大小时,此时VI等于PI,所以也没有别名问题。
再次是下图所示的,index+offset的长度大于一个page的长度,即cache的size除以WAY数大于1个page的大小时,此时VI不等于PI,所以有别名问题。
基于VIPT的别名问题总结起来就是:如果cache的size除以WAY数,小于等于1个page的大小,则VI=PI,无别名问题;如果cache的size除以WAY数,大于1个page的大小,则VI≠PI,有别名问题。
如何避免VIPT的别名问题举例:
例如:Page size是4K,CPU的cache大小64KB,cacheline大小是256B。
如果是采用4Way,显然有别名问题:
如果换成16Way,显然无别名问题:
这是我的图解系列之
Cache的歧义别名
关注我阅读更多图解