几句话说清楚45:缓存中VIPT和Set-associative的关系

Virtual Index Physical Tag(VIPT)是常见的L1数据缓存的类型。使用这种方式一是可以避免歧义和别名,二是也可以增加缓存的存取性能。

  • 歧义就是两个或更多进程访问相同的虚拟地址VA,如果都用虚拟地址VA作为缓存索引的地址,就会出现两个本不相关的进程互相影响的问题

  • 别名(Alising)就是两个不同的虚拟地址VA指向同一个物理地址PA,同样的如果都用虚拟地址作为缓存索引的地址,就会涉及到缓存一致性的问题并引发程序错误

VIPT就是用虚拟地址和物理地址相同的几位LSB和前面靠MMU从虚拟地址转换来的物理地址作为Tag来解决这两个问题的。那么VIPT和Set-associative中的几个Set,几个Way是啥关系呢?

先整一个最常见的:

L1D$ 32KB 8-way set associative

OK,CacheLine是64B,那么VIPT索引中的Offset就是6个bit,8个way,那么每个Way里set的个数就是

1
(32*1024)/8/64=64个

同样我需要6个bit作为VIPT中的index,也就是选择的Set的索引。

虚拟地址里除了这12个bit之外剩下的bit都交给MMU去做物理地址转换,转换出来的就是Tag。

同时12个bit正好等于4KB,也就是一个页表的大小,这个不是什么巧合,而是我们必须这么安排,因为虚拟地址和它对应的物理地址这12个bit相同,这样才能在MMU转换之后得到完整的物理地址。为什么选择4K是因为它和操作系统划分的页面大小相同,而虚拟地址又是操作系统的产物,两者需要配合。

物理地址相邻的数据可以放到同一个Way相邻的两个Set里,因为他们做索引的Bit是相邻的。

当物理地址增长了4K之后,该地址和它4K之前的地址具有相同的Set索引和Offset,这个时候如果另外的Way可以存放该数据就会把它放到,比如说Way1的Set1中。Way越多那么可以解决这种4K地址冲突的机会也就越多。

但Way不能无限增长,因为每次查询一个物理地址在不在缓存里的时候,都需要同时查询全部Way对应的set中是否包含有该地址的Tag,这种并行查找是非常消耗面积和功耗的。也就是为什么32KB的L1缓存最常见,是因为第一我们需要满足set+offset的bit=12(4K),如果缓存总量翻倍,那么Way的数量也必须跟着翻倍,而这并不是一个更优的方案。换句话说,当你的Cache Line长度和Way数定下来之后,缓存的总大小也就确定了。

© 2020 DecodeZ All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero