📂 操作系统 - Operating System / Chapter II 虚拟化 / Section 2 内存虚拟化 / 2-2 分段与分页

分页:快速地址转换

2026-05-13
#OS
  • 分页存在的问题

    • 分页的性能开销很大,每次执行指令的内存访问都需要额外一次内存访问,这实在太慢了,所以我们需要加速地址转换
    • 操作系统通过一个额外的硬件:地址转换旁路缓冲存储器(TLB, Translation-lookaside buffer) ,用于缓存频繁发生的地址转换。因此,TLB也被称为地址转换缓存(Address-translation cache)快表
    • 对每次内存访问,硬件都会先检查TLB,看看其中是否有期望的转换映射,如果有的话就不用再访问页表了,可以直接完成转换
  • TLB的基本算法

    • 实现流程

      1. 从虚拟地址中提取页号
      2. TLB中检查是否已经存储了该页号的映射
        • 如果存在,即TLB命中(TLB Hit)
          1. 直接从TLB项中取出页帧号
          2. 与偏移量组成期望的物理地址
        • 如果不存在,即TLB未命中
          1. 访问页表,寻找转换映射
          2. 确认该地址合法
          3. TLB中添加该转换映射
          4. 假设添加成功,然后重新访问TLB(此时必定TLB命中,从TLB项中取出页帧号,与偏移量组成期望的物理地址)
    • TLB的性质

      • TLB设计在处理器核心附近访问速度非常快
      • 如果TLB频繁未命中,地址转换的开销将会更大
      • 对于多次访问,访问目标的物理地址越集中越可能处于同一页(具有空间局部性(Spatial locality)),TLB命中率就越高
      • TLB要想快,它就必须,所以TLB能存储的项是有限的。若TLB已满但是有新的地址映射需要存储,那么可能会根据最近最少使用(LRU, Least-recently-used) 算法,用新映射替换掉某个很久未被使用的映射
      • 对于某个位置,若多次对其的访问都发生在短时间内(具有时间局部性(Temporal locality)),那么TLB的命中率将会非常非常高
  • 谁来处理TLB未命中

    • 可能是硬件,也可能是软件
    • 硬件

      • 硬件需要知道页表的物理地址和格式
      • 步骤:
        1. 发生未命中时,硬件会 ”遍历”页表
        2. 找到正确的页表项,取出想要的地址转换
        3. 更新TLB
        4. 重试该指令
    • 软件

      • 软件管理不需要硬件知道页表的确切格式,也不需要硬件做太多工作,具有灵活性简单性
      • 步骤:
        1. 发生TLB未命中时,硬件系统会抛出一个异常
        2. 这会暂停当前的指令流,将CPU的特权级别提升为内核模式
        3. 跳转至陷阱处理程序
        4. 然后由操作系统在页表中查找相关的转换映射、确认改地址合法、更新TLB、从陷阱返回
        5. 然后硬件会重试该指令
  • TLB的内容

    • 一块TLB中可能有32项、64项、128项或者更多,而一条地址映射可能在TLB的任何位置。硬件会并行地在TLB中查找期望的地址映射
    • 一条TLB项可能包含如下内容:VPNPFN其他位
      • 关于其他位:
        • TLB的有效位页表的有效位不同的
          • 页表的有效位存储的是该页是否被申请使用了
          • TLB的有效位存储的是该映射是否可用(这一项存储的是真正可用的映射,还是以前的还没被清除的废弃映射)
  • 上下文切换时对TLB的处理

    • 对于两个不同的进程相同的虚拟页对应的是不同的物理页,也就说明当前TLB中存储的映射对其他进程是无效的
    • 上下文切换同时也代表着地址空间切换,这意味着TLB也需要跟着转换
    • 让TLB支持跨多进程的虚拟化

      • 方法一:上下文切换时清空TLB
        • 这种方法非常简单,在每一次上下文切换时都清空一次TLB,这样就永远可以保证TLB对当前进程可用
        • 但是它带来的性能开销很大,毕竟如果频繁清空TLB,就会出现频繁的TLB未命中
      • 方法二:硬件支持实现跨上下文切换的TLB共享
        • TLB项中添加一个地址空间标识符(Address Space Identifier, ASID)。ASID类似进程标识符,但比一般的PID位数更少
        • 通过ASID,就可以知道该项存储的是哪个进程的地址转换映射