X86 是什么导致DTLB_LOAD_MISSES.WALK_*性能事件发生?

X86 是什么导致DTLB_LOAD_MISSES.WALK_*性能事件发生?,x86,cpu-architecture,tlb,intel-pmu,X86,Cpu Architecture,Tlb,Intel Pmu,考虑以下循环: .loop: add rsi, STRIDE mov eax, dword [rsi] dec ebp jg .loop 其中,STRIDE是一些非负整数,rsi包含指向在bss部分中定义的缓冲区的指针。这个循环是代码中唯一的循环。也就是说,它在循环之前没有被初始化或触摸。在Linux上,缓冲区的所有4K虚拟页都将按需映射到同一物理页 我已经在0-8192范围内运行了所有可能的步幅代码。每访问一页,测量到的次要和主

考虑以下循环:

.loop:
    add     rsi, STRIDE    
    mov     eax, dword [rsi]
    dec     ebp
    jg .loop
其中,
STRIDE
是一些非负整数,
rsi
包含指向在
bss
部分中定义的缓冲区的指针。这个循环是代码中唯一的循环。也就是说,它在循环之前没有被初始化或触摸。在Linux上,缓冲区的所有4K虚拟页都将按需映射到同一物理页

我已经在0-8192范围内运行了所有可能的步幅代码。每访问一页,测量到的次要和主要页面错误数分别为1和0。我还测量了Haswell在该范围内的所有跨步的以下所有性能事件

DTLB\u加载未命中。未命中导致行走:在所有TLB级别未命中 导致任意页面大小的页面漫游

DTLB\u加载\u未命中。漫游完成\u 4K:因需求而完成的页面漫游 导致任何TLB级别的4K页面漫游的加载未命中

DTLB\u加载\u未命中。漫游完成\u 2M\u 4M:由于 在任何TLB级别导致2M/4M页面移动的需求负载未命中

DTLB\u加载未命中。行走已完成\u 1G:所有TLB级别的加载未命中原因 完成的页面漫游。(1G)

DTLB\u加载\u未命中。漫游完成:在任何TLB中的任何 由于需求加载未命中而导致的页面大小

hugepages的两个计数器在所有跨步中都为零。其他三个计数器很有趣,如下图所示

对于大多数步幅,
MISS\u导致每访问一页发生5次步行
事件,
WALK\u COMPLETED\u 4K
WALK\u COMPLETED
事件每访问一页发生4次。这意味着所有完成的页面漫游都是针对4K页面的。然而,还有第五页的行走没有完成。为什么每页有这么多的页面浏览?是什么导致这些页面漫游?也许当一个页面漫游触发一个页面错误时,在处理该错误之后,会有另一个页面漫游,因此这可能会被计为两个完成的页面漫游。但是为什么会有4次完成的页面漫游和一次明显取消的漫游?请注意,Haswell上只有一次页面漫游(而Broadwell上只有两次)

我意识到有一个TLB预取器,它似乎只能预取下一页,如本文所述。根据该线程,预取器行走似乎不被视为
MISS\u cause\u A\u WALK
WALK\u COMPLETED\u 4K
事件,我同意这一点

这似乎是导致这些高事件计数的两个原因:(1)页面错误导致指令重新执行,这导致同一页面的第二次页面漫游,以及(2)TLB中错过的多个并发访问。否则,通过使用
MAP\u POPULATE
分配内存,并在load指令后添加
LFENCE
指令,一个
MISS\u会导致一个WALK
事件,每页会发生一个
WALK\u COMPLETED\u 4K
事件。如果没有
LFENCE
,每页的计数会稍大一些

我尝试让每个加载访问一个无效的内存位置。在本例中,页面错误处理程序引发SIGSEGV信号,我处理该信号以允许程序继续执行。使用
LFENCE
指令,每次访问我会得到两个
MISS\u cause\u A\u WALK
事件和两个
WALK\u COMPLETED\u 4K
事件。如果没有
LFENCE
,每次访问的计数会稍大一些

我还尝试过在循环中使用预取指令而不是按需加载。页面错误情况的结果与无效内存位置情况的结果相同(这是有意义的,因为预取在这两种情况下都失败):一个
MISS\u导致每次预取一次WALK
事件和一次
WALK\u COMPLETED\u 4K
事件。否则,如果预取是到具有有效内存内翻译的位置,则每页会发生一个
未命中事件导致\u a\u WALK
事件和一个
WALK\u COMPLETED\u 4K
事件。如果没有
LFENCE
,每页的计数会稍大一些

所有的实验都在同一个核上进行。该内核上发生的TLB故障排除中断的数量几乎为零,因此它们不会对结果产生影响。我找不到一个简单的方法来衡量操作系统在内核上驱逐TLB的次数,但我认为这不是一个相关的因素


尖峰

同样如上图所示,小步有一种特殊的模式。此外,步幅220周围有一个非常奇怪的图案(尖峰)。我能够多次复制这些模式。下面的图表放大了这个奇怪的图案,以便您可以清楚地看到它。我认为这种模式的原因是操作系统的活动,而不是性能事件的工作方式或某种微体系结构的影响,但我不确定


循环展开的影响

@BeeOnRope建议将
LFENCE
放入循环中,并将其展开零次或多次,以便更好地了解推测性无序执行对事件计数的影响。下图显示了结果。当循环展开0-63次时,每行表示一个特定的加载步长(单个迭代中有1-64个添加/加载指令对)。y轴按每页进行规格化。访问的页面数与次要页面错误数相同

我也在没有
LFENCE
的情况下进行了实验,但展开程度不同。我没有为这些做图表,但我将在下面讨论主要的区别

我们可以得出以下结论:

  • 当加载跨距大约小于128字节时,
    MISS\u会导致行走
    WALK\u COMPLETED\u 4K