从Intel上的CPUID结果了解TLB

St.*_*rio 5 x86 assembly x86-64 tlb cpuid

我正在探索说明的叶子0x02cpuid并提出了一些问题。文档中有一个表格,描述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
Run Code Online (Sandbox Code Playgroud)

这是否意味着只有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
Run Code Online (Sandbox Code Playgroud)

这里的“ 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
Run Code Online (Sandbox Code Playgroud)

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

情况4

C1H STLB Shared 2nd-Level TLB: 4 KByte/2MByte pages, 8-way associative, 1024 entries
Run Code Online (Sandbox Code Playgroud)

这是否意味着在这种情况下,所有内核之间都共享第二级TLB?那么,当没有明确指定时,TLB缓存核心是否为私有?

Had*_*ais 8

如果某些x86供应商决定提供3个级别的TLB,如何查询TLB缓存的级别数?

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

  1. 检查在将cpuidEAX设置为叶子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
Run Code Online (Sandbox Code Playgroud)

没有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
Run Code Online (Sandbox Code Playgroud)

其他字节与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
Run Code Online (Sandbox Code Playgroud)

这是与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
Run Code Online (Sandbox Code Playgroud)

对于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
Run Code Online (Sandbox Code Playgroud)

因此,有两个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
Run Code Online (Sandbox Code Playgroud)

该信息与手册一致,但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
Run Code Online (Sandbox Code Playgroud)

较旧的英特尔处理器具有单级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
Run Code Online (Sandbox Code Playgroud)

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

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

00FEFF01-000000F0-00000000-00000000
Run Code Online (Sandbox Code Playgroud)

有一个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]
Run Code Online (Sandbox Code Playgroud)

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

  • [SL 01]:描述第一级指令TLB,它是一种8路全关联高速缓存,能够缓存4KB,2MB和4MB页面的转换。
  • [SL 02]:最低有效5位代表数字5,这是根据手册的最新版本(第2卷)保留的编码。其他位指定了16位完全关联的TLB,并且能够缓存所有页面大小的转换。英特尔已在优化手册的表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的说法,AMD Zen具有三级指令TLB层次结构。这是我所知道的第一个核心微体系结构,它使用三级TLB层次结构。AMD Zen +和AMD Zen 2也很可能是这种情况(但我找不到能证实这一点的AMD资料)。cpuidL0 ITLB上似乎没有记录的信息。因此,您可能必须检查处理器是否为AMD Zen或更高版本,并为这些处理器手动提供L0 ITLB信息(所有页面大小为8个条目,可能是完全关联的)。

这里的“ 4向关联”仅仅是错字,意味着“ 4向集合关联”吗?

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

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

DTLB和uTLB都是数据TLB的名称。DTLB名称用于第一级和第二级TLB。uTLB名称仅用于第一级数据TLB,并且是micro-TLB的缩写。

这是否意味着在这种情况下,所有内核之间都共享第二级TLB?那么,当没有明确指定时,TLB缓存核心是否为私有?

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

  • ...但是我在答案中显示了一些示例,其中第二个TLB可能被称为其他名称。顺便说一下,第1级和第2级TLB的编码在叶子0x18中是不同的,因此无需诉诸此类破解。这是叶子0x18的优点之一。将来,如果添加了第3级TLB,则可能会以0x18的新编码来描述它。 (2认同)

Pet*_*des 5

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

您可以查找已知的微体系结构详细信息,以帮助检查cpuid结果的解释。例如,https //www.7-cpu.com/cpu/Skylake.html 和https://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的概念扩展到整个内核,而不仅仅是在一个内核上进行CR3更改,否则跨内核的共享TLB的价值将是有限的。(这些跨CR3更改条目旨在用于始终保持映射内核虚拟地址空间的内核,但语义是根据每个内核行为定义的,而不是真正的全局。)IIRC,PCID(进程上下文ID)也假定ID是每个核心私有的,因此即使这样做也无助于共享。请注意,启用Meltdown缓解功能后,进入内核确实会更改页表,因此即使是常见的实际用例也不是理想的选择。

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

此外,这也不是提高性能的最佳方法。脱核使用共享资源通常很慢;例如,L3数据高速缓存访​​问有很多周期。 可以从页表数据重建TLB条目,而页表数据本身可以由L3数据高速缓存进行高速缓存。(并且还通过私有L2和L1d缓存;硬件分页遍历通过PPro及更高版本上的数据缓存(有趣的事实:与P5 Pentium不同,它绕过了其片上缓存))。

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

缓存页表数据(如更高级别的页目录项)的页面步行者帮助,也和在实践中,我认为完成。因此,分页浏览可能仅需要例如通过数据缓存来获取最低的2个级别。

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

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


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

是的,DTLB =数据TLB。

uTLB can't be for the uop cache; on Intel CPUs the uop cache is virtually addressed so it doesn't need a TLB. (Not sure what Ryzen's uop-cache does, but you're looking at Intel docs).

From the size and other stuff, we can see that it's not the Unified L2TLB either. (Although from Hadi's answer, it seems that UTLB might in some cases mean Unified, i.e. combined or shared data and instructions)

I found https://software.intel.com/en-us/vtune-amplifier-help-utlb-overhead which doesn't seems to be saying that UTLB = first-level data TLB. Maybe it means "micro TLB" as in small/fast TLB with only a few entries, vs. the much larger L2TLB.

Hadi found that on some Silvermont-family CPUs, "uTLB" is for 4k pages while DTLB is for other page sizes. It does seem like "micro TLB" is the right way to interpret it.


I also found https://wikichip.org/wiki/intel/microarchitectures/kaby_lake resource regarding TLB. There is a Note: STLB is incorrectly reported as "6-way" by CPUID leaf 2 (EAX=02H). Kaby Lake erratum KBL096 recommends software to simply ignore that value. which is actually 12-way associative. cpuid bug for all Kaby Lake cpus?

Yes, it's a CPU bug that the CPU reports the wrong information via CPUID; that's why KBL096 is a CPU erratum, not a bug in software that uses cpuid.

If such software followed the normal rules, it would get results that don't match what KBL actually has. Intel is recommending that software special-case this and simply print the known correct result instead of what the cpuid data indicates.