为什么在多线程情况下,每个逻辑CPU都有自己的CR3寄存器?

3
当我们拥有支持多线程的CPU时,每个逻辑CPU都有自己的一组寄存器(至少包括CR3寄存器)。当执行不同的线程且上下文切换不发生(即在同一进程的不同线程之间切换时,TLB缓存也不会失效)时,由于我们正在处理同一进程的虚拟地址空间,那为什么需要在逻辑CPU中使用CR3寄存器去指向页表和页目录呢?这个值难道不总是与物理CPU的CR3寄存器中的值相同吗?

处理器不仅仅执行一个进程的代码。操作系统调度线程。 - Hans Passant
@HansPassant 那么TLB是如何在它们之间共享的呢?为什么它不会被无效化? - programings
它不是共享的,每个核心都有自己的TLB。 - Hans Passant
当来自不同进程的两个线程同时运行时,内存翻译是如何发生的呢? - programings
只有在不同的核心上运行时,它们才会真正同时运行。每个核心都有自己的CR3和TLB,没有什么特别的事情会发生。 - Hans Passant
@HansPassant:并不完全正确:逻辑核心与超线程共享相同的物理TLB,但它们仍然可以拥有各自独立的CR3。 - Peter Cordes
1个回答

4

由于在执行不同的线程时,我们正在处理同一进程的虚拟地址空间

这还不是HT所能做到的全部。我认为你混淆了“硬件线程”(执行上下文/逻辑核心)和“软件线程”。

两个逻辑核心运行在一个物理核心上,有一个物理iTLB / dTLB / L2TLB。逻辑核心非常独立,不必运行来自同一进程的线程。

这是像Intel的HT这样的SMT设计中的一个理想属性:如果操作系统必须小心避免将具有不同页表的线程调度到同一物理核心的不同逻辑核心上,则需要更多的核间同步。


两个不同进程的线程(具有单独的CR3页表)可以共享一个TLB,因为条目带有PCID(进程上下文ID)标记。如果我没记错,硬件虚拟化也使用类似(或相同的)标记来避免在VM退出或在客户之间切换时需要TLB清除。
操作系统可以设置PCID(CR3的低12位),以避免在上下文切换时需要TLB清除,并作为奖励启用2个进程的并发TLB使用。Linux是否使用x86 CPU的PCID功能进行TLB?如果没有,为什么?(根据那个,Linux通常不使用PCID,但我认为它用于HT。)
嗯,我不确定我的细节是否完全正确,但在物理上,TLB条目有某种标记,即使两个逻辑核心具有不同的CR3,它们也会保持分开。
根据英特尔论坛帖子,SnB系列CPU静态分配了iTLB(因此每个逻辑核心都获得了一半的条目)。这自动解决了任何共享问题。
dTLB和L2TLB是竞争共享的,因此它们需要标记。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接