TLB、PCID与ASID的故事

TLB、PCID与ASID的故事

最近学习过程中了解到TLB和PCID、ASID等概念,突然发现自己将TLB与Cache的概念容易搞混。于是深入了解这几个名词和关系,本周做一些总结。本文的各部分内容分布如下:

  1. TLB的引入
  2. TLB与Cache
  3. PCID和ASID的引入与作用

一、TLB的引入

1.1 二级页表的地址访问

让我们想象这样的应用场景:CPU执行指令时,直接访问的是虚拟地址,若想获取到内存的真实数据时,需要先将虚拟地址转化为物理地址,然后由CPU访问物理地址指向的内存空间,读取内存数据。

上述过程中,虚拟地址到物理地址的转化过程是有较大的性能消耗的。我们以二级页表为例分析地址转换过程中对内存的访问。接下来我们分析地址转化过程中涉及到的组件以及访问内存的次数:

TLB、PCID与ASID的故事_第1张图片
  • 内存:存放大量的页目录表、页表

  • MMU:利用硬件实现虚拟地址到物理地址的转换。完成以下四步,不需要编写指令指示MMU去做。(前提是操作系统要维护页表项的正确性,每次分配内存时填写相应的页表项,每次释放内存时清除相应的页表项,在必要的时候分配或释放整个页表)

    • 取出保存在TTB寄存器(translation table base register)的第一级页表(translation table)的基地址,这个基地址指的是PA,也就是说页表是直接按照这个地址保存在物理内存中的。
    • 以TTB中的内容为基地址,以VA[31:20]为索引值在一级页表中查找出一项,该页表项中保存着第二级页表(coarse page table)的基地址,这同样是物理地址,也就是说第二级页表也是直接按这个地址存储在物理内存中的。
    • 以VA[19:12]为索引值在第二级页表中查出一项,这个表项中就保存着物理页面的基地址。
    • 有了物理页面的基地址之后,加上VA[11:0]这个偏移量(2^12=4KB)就可以取出相应地址上的数据。

    这四步被称作Translation Table Walk。这个过程中访问内存中一级页面、内存中二级页面、物理页面,一次寻址其实是三次访问物理内存。这里提供一个快速计算内存访问次数的方法:

多级页表的访问次数(假设无快表):N级页表访问一个逻辑地址需要N+1次内存访问。

1.2 TLB的引入

由1.1可知,多级页表的访问需要较大的开销。TLB(translation lookaside buffer,又称转换后援缓冲器、转换旁路缓冲区、快表)的引入可以减少多级页表对内存的访问。对TLB的介绍如下:

  • TLB是关联的快速内存。TLB条目由两部分组成:键(标签)和值。当关联内存根据给定值查找时,它会同时与所有键进行比较。
  • TLB是MMU中的一块高速缓存,其中存储了当前最可能被访问到的页表项,其内容是部分页表项的一个副本。只有在TLB无法完成地址翻译任务时,才会到内存中查询页表,执行Translation Table Walk,这样就减少了页表查询导致的处理器性能下降。

1.3 TLB机制下的地址访问

在引入TLB之后,TLB和页表共同提供地址映射资源。此时,CPU访问虚拟地址的硬件操作顺序如下(可参考下图):

  • CPU内核发出虚拟地址请求读数据,TLB(translation lookaside buffer)接收到该地址。
    • 如果TLB里缓存了当前虚拟地址的页表项就不必做translation table walk了。
    • 如果TLB中没有缓存,就去物理内存中读出页表项保存在TLB中。将页号和帧号增加到TLB中。
      • 如果TLB中的条目已满,那么操作系统会选择一个来替换。
  • 页表项中不仅保存着物理页面的基地址,还保存着权限和是否允许cache的标志。MMU首先检查权限位,如果没有访问权限,就引发一个异常给CPU内核。然后检查是否允许cache。
    • 如果允许cache就启动cache和CPU内核互操作,则以虚拟地址为索引到cache中查找是否缓存了要读取的数据。
      • 如果cache中已经缓存了该数据(称为cache hit)则直接返回给CPU内核。
      • 如果cache中没有缓存该数据(称为cache miss),则发出PA从物理内存中读取数据并缓存到cache中,同时返回给CPU内核。但cache并不是只去CPU内核所需要的数据,而是把相邻的数据都去上来缓存,这称为一个cache line。
    • 如果不允许cache,那直接发出PA从物理内存中读取数据到CPU内核。
TLB、PCID与ASID的故事_第2张图片

二、TLB与CPU Cache

2.1 CPU Cache相关

CPU Cache的引入是为了缩小CPU和RAM之间的速度不匹配,高速缓存单元插在分页单元和主内存之间(可参考1.3图或2.1图,由于Cache的位置不一定,因此两图都可作为参考),它包含一个硬件高速缓存内存和一个高速缓存控制器。高速缓存内存存放内存中真正的行。高速缓存控制器存放一个表项数组,每个表项对应高速缓存内存中的一个行。

TLB、PCID与ASID的故事_第3张图片

2.2 TLB与Cache的比较

阅读几篇文章之后,本人对CPU Cache和TLB进行以下比较。实际上,TLB也可以认为是页表的Cache。
在这里插入图片描述

三、ASID与PCID的引入与作用

由于TLB保存的是进程的一部分页表,操作系统中存在多个进程,每个进程都由自己虚拟地址空间。那么在进程切换的时候,TLB中存放的到底是切换之前的进程页表?还是切换之后的进程页表?为了避免冲突,操作系统在进程切换的时候会进行TLB刷新。下述内容是与TLB刷新有关的问题。

3.1 Global TLB和non-global TLB

现代OS都将地址空间分为内核空间和用户空间。内核空间ring 0访问,用户空间ring 3访问。内核空间内容基本各个进程(包括内核线程)都差不多,内核地址空间是一样的,因此对于这部分地址翻译,无论进程如何切换,内核地址空间转换到物理地址的关系是永远不变的,在进程的时候,不需要清掉。对于用户空间,各个进程的内容都不太一样,保留只会造成混乱,需要清掉。

在这种思路引导下,CPU在加载CR3的时候,只会清掉不带Global标志的用户空间页表TLB,而不会动带有global标志的内核页表项。一个新的进程会开始一个半新的TLB,效能提高不少。

3.2 ASID

类似于Global TLB和non-global TLB的思想。有的TLB在每个TLB条目中还保存地址空间标识码(address-space identifier,ASID)。

ASID可用来唯一标识进程,并为进程提供地址空间保护。当TLB试图解析虚拟页号时,它确保当前运行进程的ASID与虚拟页相关的ASID相匹配。如果不匹配,那么就作为TLB失效。

除了提供地址空间保护外,ASID允许TLB同时包含多个进程的条目。如果TLB不支持独立的ASID,每次选择一个页表时(例如,上下文切换时),TLB就必须被冲刷(flushed)或删除,以确保下一个进程不会使用错误的地址转换。

3.3 PCID

PCID的功能和ASID类似。ASID主要在ARM。

PCID(进程上下文标识符)是在Westmere架构引入的新特性。简单来说,在此之前,TLB是单纯的VA到PA的转换表,进程1和进程2的VA对应的PA不同,不能放在一起。加上PCID后,转换变成”VA和进程上下文ID“到PA的转换表,放在一起完全没有问题了。这样进程1和进程2的页表可以和谐的在TLB中共处。

四、参考文章和问题

参考文章:

TLB的作用及工作过程

什么是TLB和PCID?为什么要有PCID?为什么Linux现在才开始使用它?

操作系统概念(第八章) 内存管理(二)

PCID is now a critical performance/security feature on x86

What’s difference between CPU Cache and TLB?

两级页表

问题:

CR3和TTB的关系?TTB基址?

你可能感兴趣的:(学习)