物理/虚拟高速缓存区别以及高速缓存重名/同名问题详解

概述

    处理器在访问存储器时,访问的地址都是虚拟地址,经过TLB和MMU的映射后变成物理地址。TBL只用于加速虚拟地址到物理地址的转换过程。得到物理地址后,若每次都直接从物理内存中读取数据,显然会变慢。实际上,处理器都配置了多级的高速缓存来加快数据的访问速度。

物理高速缓存

    当处理器查询MMU和TLB并得到物理地址之后,使用物理地址查询高速缓存,这种高速缓存称为物理高速缓存。

缺点:使用物理高速缓存的缺点就是处理器在查询MMU和TLB后才能访问高速缓存,增加了流水线的延迟时间。

    物理高速缓存的工作流程如下图:

虚拟高速缓存

    若处理器使用虚拟地址来寻址高速缓存,称为虚拟高速缓存。处理器在寻址时,首先把虚拟地址发送到高速缓存,若高速缓存里找到需要的数据,就不需要访问TLB和物理内存。

缺点:会引入问题:1.重名(aliasing)问题,2.同名(homonyms)问题

虚拟高速缓存的流程图:

总结:

1.不管是物理高速缓存和虚拟高速缓存,其实都是高速缓存,这里采用虚拟/物理来区分查询高速缓存的类别。

2.在查询TLB前,都是先确认高速缓存是否被命中。

重名(Aliasing)问题

在操作系统中,多个不同的虚拟地址有可能映射相同的物理地址。由于采用高速缓存架构,那么这些不同的虚拟地址会占用高速缓存中不同的高速缓存行,但是他们对应的是相同的物理地址。

例:VA1 和 VA2都映射到PA,在cache中有两个cache line缓存了VA1和VA2。当程序往VA1写入数据时,VA1对应的高速缓存行以及PA的内容会被更改,但是VA2还保存着旧数据。这样一个物理地址在高速缓存中就保存了两份数据,这样会产生歧义。

同名(Homonyms)问题

  •  相同的虚拟地址对应着不同的物理地址,因为操作系统中不同的进程会存在很多相同的虚拟地址,而这些相同的虚拟地址在经过MMU转换后得到不同的物理地址,就产生了同名问题。

  • 同名问题最常见的地方是进程切换。当一个进程切换到另外一个进程时,新进程使用虚拟地址来访问高速缓存的话,新进程会访问到旧进程遗留下来的高速缓存,这些高速缓存数据对于新进程来说是错误的并且是无用的。解决办法是在进程切换时把旧进程遗留下来的高速缓存都置位无效,这样就能保证新进程执行时得到一个干净的虚拟高速缓存。

高速缓存分类

  • VIVT(virtual index virtual tag):      使用虚拟地址的索引域和虚拟地址的标记域,相当于虚拟高速缓存。

  • PIPT(physical index physical tag): 使用物理地址的索引域和物理地址的标记域,相当于物理高速缓存。

  • VIPT(virtual index physical tag): 使用虚拟地址的索引和物理地址的标记域。

VIPT工作过程

    

处理器输出的虚拟地址会同时做两件事:

1.发送虚拟地址到TLB/MMU进行地址翻译。

2.在高速缓存中进行索引和查询高速缓存。

当上面两件事情做完后,从1中可以得到PFN,可以得到物理地址的标记域(PT), 可以从2中得到高速缓存的标记域(tag),对这两个标记域进行比较,如果相等,说明高速缓存命中了,如果不等,cache miss。

VIPT重名问题

采用VIPT方式也有可能导致高速缓存重名的问题。在VIPT中,使用虚拟地址的索引域来查找cache组,这时有可能导致多个cache组映射到同一个物理地址上。以linux kernel为例,它是以4KB大小为一个页面进行管理的,那么对于一个页来说,虚拟地址和物理地址的低12bit(bit(11:0))是一样的。因此,不同的虚拟地址映射到同一个物理地址,这些虚拟地址页面的低12位是一样的。如果索引域位于bit[11:0]范围内,那么就不会发生高速缓存重名。例如,cache line是32Byte,那么数据域偏移offset使用5bit,有128个cache组,那么索引域使用7bit,这种情况下刚好不会发生重名。

VIPT重名实例

以Linux kernel为例,page为4KB,假如索引域为bit[12:0],高速缓存的路(way)为8KB,则bit12索引高速缓存路(way)中的前4KB还是后4KB,bit[11:0]在4KB内进行索引。如下图:

题目

在一个32KB的4路组相联的cache中,其中cache line为32Byte,请画出这个cache的cache line、way和set的示意图。

   答: 在Cortex-A7和Cortex-A9的处理器上可以看到32KB大小的4路组相联cache。下面来分析这个cache的结构图。

cache的总大小为32KB,并且4路(way),所以每一路的大小为8KB: way_size = 32/4 = 8 (KB)

cache line的大小为32Byte,所以每一路包含的cache line数量为:num_cache_line = 8KB/32B = 256

  • 10
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

byd yes

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值