x86 - 超线程内核是否共享 MMU 和 TLB?
问题描述
据我所知,MMU 和 TLB 都没有在 Intel x86_64 的超线程内核中共享。
但是,那么,如果两个不共享地址空间的线程被调度到同一个物理内核,它们是如何运行的呢?
我认为,在这种情况下,线程没有任何机会命中 TLB,因为线程有自己的地址空间。
如果那样的话,我认为性能会被降级。
解决方案
TLB 在 Intel 处理器中的组织方式如下:
- Intel NetBurst(第一个支持 HT):复制了 ITLB。DTLB 是竞争性共享的。
- Intel Nehalem(第二个支持 HT)、Westmere、Sandy Bridge 和 Ivy Bridge:复制了大页面 ITLB。小页面 ITLB 是静态分区的。所有 DTLB 都是竞争性共享的。
- Intel Haswell、Broadwell 和 Skylake:小页面 ITLB 是动态分区的。大页面 ITLB 被复制。优化手册(2019 年 9 月)的表 2-12 表示该策略对于其他 TLB 是“固定的”。我认为这意味着静态分区。但是根据题为Translation Leak-aside Buffer: Defeating Cache Side-channel Protections with TLB Attacks (Section 6) 的论文的实验结果,似乎“固定”意味着竞争共享。这与早期和后来的微架构是一致的。
- Sunny Cove:ITLB 是静态分区的。所有 DTLB 和 STLB 都是竞争共享的。
- AMD Zen、Zen+、Zen 2 (Family 17h):所有 TLB 都是竞争共享的。
参考:
- 对于 NetBurst:https ://software.intel.com/en-us/articles/introduction-to-hyper-threading-technology 。
- 对于其他英特尔微架构:信息可在优化参考手册中找到。
- 对于 AMD 微架构:该信息可在软件优化指南中找到。
我不清楚 TLB 在任何英特尔凌动微架构中是如何组织的。我认为 L1 DTLB 和 STLB(在 Goldmont Plus 中)或 L2 DTLB(在早期微架构中)是共享的。根据英特尔 SDM V3(2019 年 10 月)第 8.7.13.2 节:
在支持英特尔超线程技术的处理器中,数据缓存 TLB 是共享的。指令高速缓存 TLB 可以在每个逻辑处理器中复制或共享,具体取决于不同处理器系列的实现细节。
虽然这并不准确,因为 ITLB 也可以分区。
我不知道 Intel Atoms 中的 ITLB。
(顺便说一下,在较旧的 AMD 处理器中,所有 TLB 都是按内核复制的。请参阅:Physical core and Logical cores on different cpu AMD/Intel。)
当一个 TLB 被共享时,每个 TLB 条目都被标记为分配它的逻辑处理器 ID(单个位值,与进程上下文标识符不同,可以禁用或不支持)。如果另一个线程被调度在逻辑内核上运行,并且该线程访问的虚拟地址空间与前一个线程不同,则操作系统必须将第一级页面结构的相应基本物理地址加载到 CR3 中。每当写入 CR3 时,内核都会自动刷新所有共享 TLB 中的所有条目,这些 TLB 标记有逻辑内核的 ID。还有其他操作可能会触发此刷新。
分区和复制的 TLB 不需要使用逻辑核心 ID 进行标记。
如果支持并启用进程上下文标识符 (PCID),则不使用逻辑核心 ID,因为 PCID 更强大。请注意,分区和复制的 TLB 使用 PCID 进行标记。
(请注意,还有其他分页结构缓存,它们的组织方式类似。)
(请注意,通常 TLB 被认为是 MMU 的一部分。关于 MMU 的 Wikipedia文章显示了一本书的旧版本中的一个图,表明它们是分开的。但是,该书的最新版本已删除该图并说 TLB 是 MMU 的一部分。)
推荐阅读
- python - Python Scan 文件夹和子文件夹。子文件夹。只处理指定文件
- c++ - GCC -l(链接库选项)在未链接时显示相同的输出
- java - 遍历数组抛出 NullPointerException
- c++ - 通过指向 const 对象的指针的引用传递
- mysql - 存储过程输入接受
- javascript - 如何在 tsconfig.json 设置之外编译根级 .ts 文件?
- android - 如何在 Android 11 中使用 Firebase 云消息传递的通知中设置自定义声音?
- firebase - 是否可以限制用户可以登录 Firebase 应用的设备数量?
- javascript - 使用javascript从svg中删除宽度和高度
- python - 如何在数据类 asdict() 输出中包含 ClassVars?