从Intel上的CPUID结果了解TLB

时间:2019-09-27 06:15:20

标签: assembly x86 x86-64 tlb cpuid

我正在探索0x02指令的第cpuid页,并提出了一些问题。表格in the documentation描述了cpuid结果对TLB配置的含义。他们在这里:

情况1

56H TLB Data TLB0: 4 MByte pages, 4-way set associative, 16 entries
[...]
B4H TLB Data TLB1: 4 KByte pages, 4-way associative, 256 entries

这是否意味着只有2个级别的TLB?如果某些x86供应商决定提供3个级别的TLB,如何查询TLB缓存的级别?

情况2

57H TLB Data TLB0: 4 KByte pages, 4-way associative, 16 entries
[...] 
B4H TLB Data TLB1: 4 KByte pages, 4-way associative, 256 entries

这里的“ 4向关联”只是一个错字,意味着“ 4向设置关联”?

情况3

55H TLB Instruction TLB: 2-MByte or 4-MByte pages, fully associative, 7 entries
[...]
6AH Cache uTLB: 4 KByte pages, 8-way set associative, 64 entries
6BH Cache DTLB: 4 KByte pages, 8-way set associative, 256 entries

DTLB代表数据TLB吗? uTLB是什么意思? uops-TLB?这里考虑哪个TLB缓存级别?

案例4

C1H STLB Shared 2nd-Level TLB: 4 KByte/2MByte pages, 8-way associative, 1024 entries

这是否意味着在这种情况下,所有内核之间都共享第二级TLB?因此,如果未明确指定,则TLB缓存核心是否为私有?

2 个答案:

答案 0 :(得分:8)

  

在某些x86供应商的情况下如何查询TLB缓存的级别数   决定提供3个级别的TLB?

叶0x2只能在Intel处理器上返回TLB信息。它在所有当前的AMD处理器上保留。在当前所有的Intel处理器上,没有唯一的数字可以告诉您TLB级别的数量。确定级别数的唯一方法是枚举所有与TLB相关的cpuid叶子或子叶子。以下算法可在支持cpuid指令的所有当前Intel处理器上运行(直到并包括Ice Lake,Goldmont Plus和Knights Mill):

  1. 检查在执行cpuid并将EAX设置为叶子0x2时返回的四个寄存器EAX,EBX,ECX和EDX中是否存在值0xFE。
  2. 如果0xFE不存在,请枚举四个寄存器中的所有字节。基于Intel手册第2卷(编号325383-070US)的表3-12,将存在一个或两个数据TLB描述符,它们可以缓存4KB转换。英特尔手册为可缓存数据访问转换的TLB使用以下不同名称:数据TLB,数据TLB0,数据TLB1,DTLB,uTLB和共享的第二层TLB。如果有两个这样的描述符,则级别数为两个。具有更大数量的TLB号的描述符是用于第二级TLB的描述符。如果只有一个这样的描述符,则级别数为一。
  3. 如果存在0xFE,则需要从cpuid叶0x18获得TLB信息。枚举所有有效子叶,直到最大有效子叶数。如果至少有一个子叶的EDX的至少两个有效位等于11,则TLB级别的数量为2。否则,TLB级别数为1。

Ice Lake和Goldmont Plus处理器的TLB信息显示在叶子0x18中。该叶子为编码TLB信息提供了更大的灵活性。叶子0x2中提供了所有其他当前Intel处理器的TLB信息。我不了解Knights Mill(如果有人可以访问Knights Mill,请考虑共享cpuid转储)。

确定TLB级别的数量不足以完全描述级别之间的相互关系。当前的英特尔处理器实现两种不同的2级TLB层次结构:

  • 第二级TLB可以缓存数据加载(包括预取),数据存储和指令取回的转换。在这种情况下,第二级TLB被称为“共享的第二级TLB”。
  • 第二级TLB可以缓存数据加载和存储的转换,但不能缓存指令提取。在这种情况下,以下任何一种都称为第二级TLB:数据TLB,数据TLB1或DTLB。

我将基于InstLatx64cpuid转储讨论几个示例。在启用了超线程的 Haswell 处理器之一上,叶0x2在四个寄存器中提供以下信息:

76036301-00F0B5FF-00000000-00C10000

没有0xFE,因此该叶本身中包含TLB信息。根据表3-12:

76: Instruction TLB: 2M/4M pages, fully associative, 8 entries
03: Data TLB: 4 KByte pages, 4-way set associative, 64 entries
63: Data TLB: 2 MByte or 4 MByte pages, 4-way set associative, 32 entries and a separate array with 1 GByte pages, 4-way set associative, 4 entries
B5: Instruction TLB: 4KByte pages, 8-way set associative, 64 entries
C1: Shared 2nd-Level TLB: 4 KByte/2MByte pages, 8-way associative, 1024 entries

其他字节与TLB不相关。

与英特尔优化手册的表2-17(编号248966-042b)相比,存在一个差异。表2-17提到了4KB条目的TLB指令具有128条条目(4路关联),并且在两个超线程之间动态分区。但是TLB转储说它是8路关联的,只有64个条目。对于具有128个条目的4路ITLB,实际上没有编码,因此我认为手册是错误的。无论如何,C1显示有两个TLB级别,第二个级别缓存数据和指令翻译。

Goldmont 处理器之一上,叶0x2在四个寄存器中提供以下信息:

6164A001-0000FFC4-00000000-00000000

以下是与TLB相关的字节的解释:

61: Instruction TLB: 4 KByte pages, fully associative, 48 entries
64: Data TLB: 4 KByte pages, 4-way set associative, 512 entries
A0: DTLB: 4k pages, fully associative, 32 entries
C4: DTLB: 2M/4M Byte pages, 4-way associative, 32 entries

对于4KB页面有两个数据TLB,一个具有512个条目,另一个具有32个条目。这意味着处理器具有两个级别的TLB。第二级称为“数据TLB”,因此它只能缓存数据转换。

优化手册的表19-4提到Goldmont中的ITLB支持大页面,但是TLB信息中没有此信息。数据TLB信息与手册的表19-7一致,除了在手册中将“数据TLB”和“ DTLB”分别称为“ DTLB”和“ uTLB”。

Knights Landing 处理器之一上,叶0x2在四个寄存器中提供以下信息:

6C6B6A01-00FF616D-00000000-00000000
6C: DTLB: 2M/4M pages, 8-way set associative, 128 entries
6B: DTLB: 4 KByte pages, 8-way set associative, 256 entries
6A: uTLB: 4 KByte pages, 8-way set associative, 64 entries
61: Instruction TLB: 4 KByte pages, fully associative, 48 entries
6D: DTLB: 1 GByte pages, fully associative, 16 entries

因此有两个TLB级别。第一个由用于不同页面大小的多个结构组成。 4KB页面的TLB称为uTLB,其他页面大小的TLB称为DTLB。第二级TLB称为DTLB。这些数字和名称与手册中的表20-3一致。

Silvermont 处理器提供以下TLB信息:

61B3A001-0000FFC2-00000000-00000000
61: Instruction TLB: 4 KByte pages, fully associative, 48 entries
B3: Data TLB: 4 KByte pages, 4-way set associative, 128 entries
A0: DTLB: 4k pages, fully associative, 32 entries
C2: DTLB: 4 KByte/2 MByte pages, 4-way associative, 16 entries

此信息与手册一致,但C2除外。我认为应该说“ 4 MB / 2 MByte”,而不是“ 4 KB / 2 MByte”。这可能是手册中的错字。

英特尔 Penryn 微体系结构是一个示例,其中TLB信息使用名称TLB0和TLB1来引用第一级和第二级TLB:

05: Data TLB1: 4 MByte pages, 4-way set associative, 32 entries
B0: Instruction TLB: 4 KByte pages, 4-way set associative, 128 entries
B1: Instruction TLB: 2M pages, 4-way, 8 entries or 4M pages, 4-way, 4 entries
56: Data TLB0: 4 MByte pages, 4-way set associative, 16 entries
57: Data TLB0: 4 KByte pages, 4-way associative, 16 entries
B4: Data TLB1: 4 KByte pages, 4-way associative, 256 entries

较旧的Intel处理器具有单级TLB层次结构。例如,这是 Prescott 的TLB信息:

5B: Data TLB: 4 KByte and 4 MByte pages, 64 entries
50: Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 64 entries

所有Intel 80386处理器和某些Intel 80486处理器都包含单级TLB层次结构,但不支持cpuid指令。在80386之前的处理器上,没有分页。如果您希望以上算法在所有Intel x86处理器上都可以使用,则还必须考虑这些情况。可以在here上找到的英特尔文档编号241618-025,标题为“处理器标识和CPUID指令”,在第7章中讨论了如何处理这些情况。

我将讨论一个示例,其中TLB信息出现在叶子0x18中而不是叶子0x2中。就像我之前说过的那样,现有的唯一具有0x18 TLB信息的Intel处理器是Ice Lake和Goldmont Plus处理器(也许还有Knights Mill)。 Ice Lake 处理器的叶子0x2转储为:

00FEFF01-000000F0-00000000-00000000

有一个0xFE字节,因此TLB信息存在于功能更强大的叶子0x18中。叶0x18的子叶0x0指定最大有效子叶为0x7。这是子叶0x0到0x7的转储:

00000007-00000000-00000000-00000000 [SL 00]
00000000-00080007-00000001-00004122 [SL 01]
00000000-0010000F-00000001-00004125 [SL 02]
00000000-00040001-00000010-00004024 [SL 03]
00000000-00040006-00000008-00004024 [SL 04]
00000000-00080008-00000001-00004124 [SL 05]
00000000-00080007-00000080-00004043 [SL 06]
00000000-00080009-00000080-00004043 [SL 07]

英特尔手册介绍了如何解码这些位。每个有效的子叶描述一个单一的TLB结构。如果EDX的最低有效五位不全为零,则子叶有效(即描述TLB结构)。因此,子叶0x0无效。接下来的七个子叶都是有效的,这意味着Ice Lake处理器中有7个TLB描述符。 EDX的最低有效五位指定TLB的类型,接下来的三位指定TLB的级别。通过解码子叶位获得以下信息:

  • [SL 01] :描述了一级指令TLB,它是8路完全关联的高速缓存,能够缓存4KB,2MB和4MB页面的翻译。
  • [SL 02] :最低有效5位代表数字5,这是根据手册的最新版本(第2卷)保留的编码。其他位指定TLB,它是16路完全关联的,并且能够缓存所有页面大小的转换。英特尔已在优化手册的表2-5中提供了有关Ice Lake中TLB的信息。最接近的匹配表明,保留的编码5最有可能代表数据存储转换的第一级TLB。
  • [SL 03] :最低有效5位代表数字4,根据手册的最新版本,该数字也是保留的编码。与表2-5的最接近匹配表明,它代表可缓存4KB转换的数据加载的第一级TLB。方式和集合的数量与表2-5相匹配。
  • [SL 04] :类似于子叶0x3。与表2-5的最接近匹配表明,它代表可缓存2MB和4MB转换的数据加载的第一级TLB。方式和集合的数量与表2-5相匹配。
  • [SL 05] :类似于子叶0x3。与表2-5的最接近匹配表明,它代表可缓存1GB转换的数据加载的第一级TLB。方式和集合的数量与表2-5相匹配。
  • [SL 06] :描述由8种方式和128组组成的二级统一TLB,能够缓存4KB,2MB和4MB页面的翻译。
  • [SL 07] :描述由8种方式和128组组成的二级统一TLB,能够为4KB和1GB页面缓存翻译。

表2-5实际上提到只有一个统一的TLB结构,但是一半方法只能缓存4KB,2MB和4MB页面的翻译,另一半只能缓存4KB和1GB页面的翻译。因此,第二级TLB的TLB信息与手册一致。但是,指令TLB的TLB信息与表2-5不一致。该手册可能是正确的。在TLB信息转储中,用于4KB页面的ITLB似乎与用于2MB和4MB页面的ITLB混杂在一起。

在AMD处理器上,分别在叶子8000_0005和8000_0006中提供了第一级和第二级TLB的TLB信息。有关更多信息,请参见AMD手册第3卷。早于K5的AMD处理器不支持cpuid,其中一些处理器包含单级TLB。因此,如果您关心这些处理器,则需要一种替代机制来确定TLB是否存在。 Zen 2在两个TLB级别均增加了1GB支持。有关这些TLB的信息,请参见第8000_0019页。

AMD Zen具有三级指令TLB层次结构according to AMD。这是我所知道的第一个核心微体系结构,它使用三级TLB层次结构。 AMD Zen +和AMD Zen 2也很可能也是这种情况(但我找不到能证实这一点的AMD资料)。 L0 ITLB上似乎没有记录的cpuid信息。因此,您可能必须检查处理器是否为AMD Zen或更高版本,并为这些处理器手动提供L0 ITLB信息(所有页面大小为8个条目,可能是完全关联的)。

  

这里的“ 4向关联”只是一个错字,意思是“ 4向设置”   关联的?”

这不是错字。这些术语是同义词,并且都是常用术语。

  

DTLB代表数据TLB吗? uTLB是什么意思? uosp-TLB?哪个TLB   这里考虑缓存级别?

DTLB和uTLB都是数据TLB的名称。 DTLB名称用于第一级和第二级TLB。 uTLB名称仅用于第一级数据TLB,而微型TLB的缩写。

  

这是否意味着在那种情况下第二级TLB在   所有核心?因此,如果未明确指定,则TLB缓存核心   私人的吗?

此处的“共享”一词是指“统一的”,因为在数据和指令翻译中都可以缓存。英特尔应该将其称为UTLB(大写U)或统一TLB,这是现代叶子0x18中使用的名称。

答案 1 :(得分:5)

将我的评论收集为答案。 Hadi的答案可以更直接地回答更多的问题,但这希望是有关TLB的有用背景,以帮助您了解其设计方式及其含义。

您可以查找已知的微体系结构详细信息,以帮助检查您对cpuid结果的理解。例如,https://www.7-cpu.com/cpu/Skylake.htmlhttps://www.realworldtech.com/haswell-cpu/5/包含有关这些Intel uarches的详细信息。其他资料包括英特尔的优化手册,也可能包括Agner Fog的微架构指南。 IDK为什么有些人说“设置”关联,而另一些人则不说;这不是重要的AFAIK。

(在某些情况下,对什么是合理的设计应用常识性推理。令人惊讶的结果可能是正确的,但需要更多检查。)

  

这是否意味着只有2个级别的TLB?

是的,主流x86 CPU仍然“仅”使用2级TLB,而2级是统一的(指令/数据转换)。

第一层被拆分为L1iTLB(紧密耦合到前端获取阶段)和L1dTLB(紧密耦合到加载/存储单元)。二级TLB已统一。

在当前的Intel CPU上,L2TLB本质上是受害者缓存。页面漫游器结果仅添加到需要它的L1 TLB中,仅在从L1iTLB或L1dTLB中逐出后才移至L2TLB。我忘记了它们是否是排他性的(即交换条目以确保没有重复项),但我不这么认为。无论如何,有趣的事实:将代码和数据保留在同一页面中仍然可以触发代码和数据的单独页面遍历,因为代码的iTLB遗漏不会将结果放在dTLB遗漏可以看到的任何地方,而不是立即。至少页表数据本身将位于L1d高速缓存中,如果访问在时间上相互靠近,则页漫游器可以快速获取它。

  

这是否意味着在这种情况下,所有内核之间都共享第二级TLB?因此,如果未明确指定,则TLB缓存核心是否为私有?

TLB始终是每个内核专用的,即使您愿意,在设计一种共享条目的方式时也存在重大问题。

与内存内容不同,翻译和invlpg无效是每个内核专用的。每个逻辑核心都有自己的指向顶层页面目录的CR3指针。有时,多个核心正在运行同一进程的线程,因此它们具有相同的CR3,但有时却没有。除非通过x86 ISA系统编程细节扩展了PTE的概念,而这些PTE在各个内核之间是全局的,而不仅仅是在一个内核上的CR3更改之间,否则跨内核的共享TLB的价值将是有限的。 (这些跨CR3更改条目旨在用于始终保持映射内核虚拟地址空间的内核,但是语义是根据每个内核行为定义的,而不是真正的全局。)IIRC,PCID(进程上下文ID)也假定ID是每个核心私有的,因此即使这样做也无助于共享。请注意,启用Meltdown缓解功能后,进入内核确实会更改页表,因此即使是常见的实际用例也不是理想的选择。

因此,无论如何,标记共享的TLB条目以根据现有ISA规则维护正确性都存在大量潜在的复杂性。启用超线程后,Sandybridge甚至可以在逻辑内核之间静态分区小页面L1iTLB,并复制大页面L1iTLB(Kanter, RealWorldTech)。

此外,这也不是提高性能的最佳方法。脱核使用共享资源通常很慢;例如L3数据高速缓存访​​问有很多周期。 TLB条目可以从可以由L3数据缓存自身缓存的页表数据中重建。(还有私有L2和L1d缓存; Hardware page-walk fetches through the data caches on PPro and later(有趣的事实:与P5 Pentium不同绕过了片上缓存)。

与其去核外(等待时间可能类似于L3缓存)来检查假设的共享L3TLB(可能仍会遗漏),使用本地页面重建TLB条目更有意义。 Skylake添加了第二个HW page-walker,它可以并行处理两个TLB未命中(或推测性填充);这可能比共享的L3TLB有更多的帮助,即使在最佳情况下,所有内核都运行同一进程的线程并具有许多共享的工作集。如果页表数据必须来自核心以外,则将页表数据处理为TLB条目可能只占总周期的一小部分。

在页面漫游器内 内缓存页面表数据(例如更高级别的页面目录条目)也很有帮助,我认为这是在实践中完成的。因此,分页浏览可能只需要例如通过数据缓存来获取最低的2个级别。

TL:DR:从现有的专用+共享数据高速缓存中快速进行页面遍历硬件读取,并进行推测性的TLB预取,可以解决共享TLB可能遇到的相同问题,并有助于在单独处理的情况下提高性能。 / strong>还能避免很多问题。

与共享的L3TLB相比,添加更多/甚至更好的页面遍历硬件将在帮助更多情况下发挥更大作用。


  

DTLB代表数据TLB吗? uTLB是什么意思? uops-TLB?这里考虑哪个TLB缓存级别?

是的,DTLB =数据TLB。

uTLB不能用于uop缓存;在Intel CPU上,uop缓存已得到虚拟寻址,因此不需要TLB。 (不知道Ryzen的uop缓存做什么,但是您正在查看Intel文档)。

从大小和其他方面来看,我们也不是Unified L2TLB。 (尽管从哈迪的答案来看,在某些情况下,UTLB似乎意味着统一的,即合并或共享的数据和指令)

我发现https://software.intel.com/en-us/vtune-amplifier-help-utlb-overhead似乎并不是说UTLB =一级数据TLB。也许它的意思是“微型TLB”,就像只有少量条目的小型/快速TLB一样,而大型L2TLB则更是如此。

Hadi发现,在某些Silvermont系列CPU上,“ uTLB”用于4k页,而DTLB用于其他页面大小。似乎“微型TLB”是解释它的正确方法。


  

我还发现了https://wikichip.org/wiki/intel/microarchitectures/kaby_lake关于TLB的资源。有一个注释: STLB被CPUID叶2(EAX = 02H)错误地报告为“ 6-way”。 Kaby Lake勘误表KBL096建议使用软件来忽略该值。这实际上是12向关联的。 cpuid对于所有Kaby Lake CPU的错误?

是的,这是一个CPU错误,即CPU通过CPUID报告错误信息。这就是KBL096是CPU错误的原因,而不是使用cpuid的软件中的错误。

如果此类软件遵循正常规则,则将获得与KBL实际不匹配的结果。英特尔建议软件对此进行特殊处理,并仅打印已知的正确结果而不是cpuid数据所指示的结果。