本文将mark下Cache缓存设计策略中的PIPT(Physically-Indexed, Physically-Tagged)、VIVT(Virtually-Indexed, Virtually-Tagged)和VIPT(Virtually-Indexed, Physically-Tagged)的相关notes。

Basic knowledge

Cache 本质就是一个硬件 hash 表(Tag RAM + DATA RAM),一般来说 Cache 的大小指的是DATA RAM 的大小,并不包括 Tag RAM 的物理空间。如下图所示,以一个 32 位内存地址为例,其中 [0, 4] 属于 Offset 字段,[5, 12] 属于 Index 字段,[13, 31] 属于 Tag 字段。

PIPT

工作流程

  1. CPU 发出虚拟地址 (VA)
  2. MMU (内存管理单元) 将 VA 翻译成物理地址 (PA)(通过查询 TLB 或页表)
  3. 使用 PA 的一部分索引缓存
  4. 使用 PA 的剩余部分作为标签,与索引找到的缓存行中的标签进行比较
  5. 如果标签匹配且有效位为真,则缓存命中,数据返回给 CPU;否则缓存未命中

缺点

速度慢,缓存查找必须等待MMU完成虚拟地址到物理地址的转换后才能开始,这增加了访问latency。

VIVT

工作流程

  1. CPU 发出虚拟地址 (VA)
  2. 同时:
    • 使用 VA 的一部分直接索引缓存,使用 VA 的剩余部分作为标签,与索引找到的缓存行中的标签进行比较
    • MMU 将 VA 翻译成物理地址 (PA)
  3. 如果标签匹配、有效位为真,并且 MMU 转换成功(地址有效),则缓存命中,数据返回给 CPU;否则缓存未命中

缺点

  • 歧义问题: 不同的物理地址(不同的数据)可能具有相同的虚拟地址索引和标签部分(如果映射不同)。这会导致一个缓存行错误地对应多个物理地址的数据。
  • 同名问题: 同一个物理地址(同一份数据)被映射到不同的虚拟地址时,会在缓存中产生多个副本(不同虚拟标签)。修改一个副本不会自动更新另一个副本,导致数据不一致。
  • 需要操作系统干预: 内核在切换进程上下文或修改页表映射时,必须清空(flush)整个或部分缓存以避免歧义和同名问题,开销巨大。

VIPT

工作流程

  1. CPU 发出虚拟地址 (VA)。
  2. 同时:
    • 使用 VA 的一部分直接索引缓存
    • MMU (通过 TLB) 将 VA 翻译成物理地址 (PA)
  3. 使用 PA 的(相应)部分作为标签,与步骤2中索引找到的缓存行中的标签进行比较
  4. 如果标签匹配且有效位为真,则缓存命中,数据返回给 CPU;否则缓存未命中

参考资料:

  1. Virtual Memory: 13 TLBs and Caches
  2. GPU TLB 与 MIG 切分:真的完全物理隔离吗?
  3. Caches: Policies and Interactions with VM