首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

CPU设计之Cache-寻址方式

在前面讲缓存数据放置时讲到,缓存控制器通过地址的高位来做标签(Tag)和索引(Index)判断是否命中。但是我们并没有说这个地址是虚拟地址(virtual address)还是物理地址(physical address)。

现代的处理器系统都支持虚拟存储。在虚拟存储系统中,程序可以假设整个地址空间都是可用的。系统通过两种类型的地址:虚拟地址和物理地址,营造了程序拥有较大地址空间的抽象。操作系统以页为粒度(通常4KB为一页),维护地址页表,将虚拟地址翻译为物理地址。负责地址翻译的组件被称作内存管理单元(Memory Management Unit,MMU)。

页表由操作系统维护,放在主存中。由于虚拟空间较大,页表往往采用层次结构,需要多次访问才能一个虚拟页地址转换为一个物理页地址。如果每次存储访问都要访问页表,那么cache的访问时延将很大。为了加速页表访问,大多数的处理器都会采用旁路转换缓冲(TranslationLookaside Buffer,TLB),作为一个高速缓存保存最近最常用的页表项。因为一个页比一个高速缓存块大很多,所以TLB只需要很少的表项就能覆盖很大的空间。可以把TLB理解为专门做地址转换用的一小块cache。

在高速缓存中,虚拟地址和物理地址都可以用于索引和标签比较。根据标签和索引是虚拟地址还是物理地址,缓存寻址方式分为以下几类:

第一种是虚拟索引虚拟标签(Virtual Index Virtual Tag,VIVT),即通过虚拟地址的索引位进行缓存寻址,并将虚拟地址中的标签位保存在缓存的标签阵列。通过虚拟寻址,在访问cache时不需要物理地址,因此TLB和L1的访问可以并行执行,访问TLB的延迟可以被隐藏掉。但是这种方式的缺点也很明显,首先每个进程都有自己的页表,也就是说相同的虚拟页地址在不同进程中其对应的物理地址很可能不同。这就是所说的歧义(ambiguity)问题。举个例子,假设A进程虚拟地址0x1000映射物理地址0x2000。B进程虚拟地址0x1000映射物理地址0x3000。当A进程运行时,访问0x1000地址会将物理地址0x2000的数据加载到cache中。随后切换到B进程的时候,B进程访问0x1000会cache hit,此时B进程就访问了错误的数据。想要避免歧义的发生,当切换进程的时候,可以选择flush所有的cache。因此,虚拟寻址的cache无法在多个进程间共享数据。切换后的进程刚开始执行的时候,将会由于大量的cachemiss导致性能损失。VIVT还要面临另一个问题:别名(alias)。当不同的虚拟地址映射相同的物理地址,而这些虚拟地址的index不同,此时就发生了别名现象。一个例子。虚拟地址0x1000和0x4000都映射到相同的物理地址0x8000。这意味着进程既可以从0x1000读取数据,也能从地址0x4000读取数据。那么有可能同一个物理地址的数据会加载到不同的cache line。如果进程先访问0x1000把数据加载进一条cache line,接着访问0x4000把相同物理地址的数据加载进另一条cache line,然后将0x1000地址数据修改,当再次访问0x4000的时候由于cache hit导致读取到旧的数据。这就造成了数据不一致现象。想解决这个问题,可以把0x1000和0x4000地址设成uncache,对这些地址的访问不通过cache,但是这样就损失了cache带来的性能好处。

图1 VIVT的高速缓存

第二种是物理索引物理标签(Physical Index Physical Tag,PIPT),即通过物理地址的索引位进行缓存寻址,并将物理地址中的标签位保存在缓存的标签阵列中。这种方式的缺点是在生成cache所需的物理地址时,需要访问TLB进行地址翻译,因此访问TLB造成的延迟会加在cache的访问时间上。这就相当于L1的访问时间延长了一倍,显著影响性能。PIPT的优点是软件层面基本不需要任何的维护就可以避免歧义和别名问题。在Linux内核中,可以看到针对PIPT高速缓存的管理函数都是空函数,无需任何的管理。

图2 PIPT的高速缓存

第三种是虚拟索引物理标签(Virtual Index Physical Tag,VIPT),索引位不需要通过TLB,可以立即对缓存进行访问,标签位经过TLB,物理地址标签与缓存中的标签进行对比,从而决定是hit还是miss。这种寻址方式的缺点是L1的大小受限,目前看这种缺陷并不严重,因为从性能角度考虑,L1的大小已经受限了。VIPT以物理地址部分位作为标签位,因此不会存在歧义问题。但是有可能会存在别名问题,取决于cache的数据放置策略和操作系统的页表管理,具体就不分析了。

图3 VIPT的高速缓存

可能有细心的同学要问了,“根据排列组合来说,还应该有PIVT啊”。之所以没有文献提,主要是因为PIVT在速度上很慢,还有歧义和别名问题,完全没有优势。

最后总结一下,VIVT软件维护成本过高,是最难管理的高速缓存。目前主要使用PIPT和VIPT。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230216A09DX300?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券