【发布时间】:2017-10-03 07:40:09
【问题描述】:
我正在尝试将一些性能工程技术应用于 Dijkstra 算法的实现。为了找到(幼稚且未优化的)程序中的瓶颈,我使用perf 命令记录缓存未命中的数量。相关代码的sn-p如下,找到距离最小的未访问节点:
for (int i = 0; i < count; i++) {
if (!visited[i]) {
if (tmp == -1 || dist[i] < dist[tmp]) {
tmp = i;
}
}
}
对于LLC-load-misses 度量,perf report 显示程序集的以下注释:
│ for (int i = 0; i < count; i++) { ▒
1.19 │ ff: add $0x1,%eax ▒
0.03 │102: cmp 0x20(%rsp),%eax ▒
│ ↓ jge 135 ▒
│ if (!visited[i]) { ▒
0.07 │ movslq %eax,%rdx ▒
│ mov 0x18(%rsp),%rdi ◆
0.70 │ cmpb $0x0,(%rdi,%rdx,1) ▒
0.53 │ ↑ jne ff ▒
│ if (tmp == -1 || dist[i] < dist[tmp]) { ▒
0.07 │ cmp $0xffffffff,%r13d ▒
│ ↑ je fc ▒
0.96 │ mov 0x40(%rsp),%rcx ▒
0.08 │ movslq %r13d,%rsi ▒
│ movsd (%rcx,%rsi,8),%xmm0 ▒
0.13 │ ucomis (%rcx,%rdx,8),%xmm0 ▒
57.99 │ ↑ jbe ff ▒
│ tmp = i; ▒
│ mov %eax,%r13d ▒
│ ↑ jmp ff ▒
│ } ▒
│ } ▒
│ }
那么我的问题是:为什么jbe 指令会产生如此多的缓存未命中?如果我没记错的话,这条指令根本不需要从内存中检索任何东西。我认为这可能与指令缓存未命中有关,但即使使用L1-dcache-load-misses 仅测量 L1 数据缓存未命中也表明该指令中有很多缓存未命中。
这有点难倒我。谁能解释这个(在我看来)奇怪的结果?提前谢谢你。
【问题讨论】:
-
Stephen,您的确切 CPU 型号是什么(查找微架构名称和可用 PMU 事件集)。 LLC-load-misses 是合成性能事件,它映射到不同的硬件 PMU 事件(另请查看
pref record ... -vvv ./program),其中一些是准确的,而另一些则不准确。对于不精确的事件,会报告错误的指令地址,有时偏差很小,有时偏差很大(即使对于不同的功能)。英特尔中有十个确切的事件“PEBS” - 试试dmesg | grep -i pebs。尝试 Intel 的 github.com/andikleen/pmu-tools 中的ocperf工具来使用真实的硬件事件 -
感谢您的回复,osgx。我运行它的 CPU 是 Intel Core i5 750 (Nehalem)。我不知道
LLC-load-misses是一个不精确的事件,并假设它是精确的,因为perf list将其列为硬件缓存事件。如果我理解正确,我需要使用rXXXXXXX原始硬件事件,但是我不知道如何从我在这里打开的 Nehalem 性能工程手册中推断出确切的事件名称:software.intel.com/sites/products/collateral/hpc/vtune/… -
Stephen,并非所有硬件事件都是准确的。使用 ocperf 获取 intel 事件名称,无需手动转换为 rXXXX 原始代码。
-
Stephen,您的 linux 内核版本(或 linux 发行版)是什么?尝试
valgrind程序和kcachegrindGUI 的cachegrindprofiler/cache 模拟器工具,以获取有关代码如何工作的基本概念(每个instr 的确切指令执行计数),热路径在哪里以及缓存密集型代码在哪里.但请注意,它只是模拟器,其结果不等于真正的 cpu 运行和真正的缓存方法;而且它非常慢 - 与原生相比,在 valgrind 下运行速度预计会慢 20-30 倍。 -
PS:高位计数器附近有两条指令:"ucomis (%rcx,%rdx,8),%xmm0 + ↑ jbe",其中ucomis为some kind of compare,带内存参数。 Intel CPU 可以将一些操作组合(realworldtech.com/nehalem/5“成单个 uop,CMP+JCC”)融合在一起,而 cmp + 条件跳转是要融合的常见指令(您可以使用 Intel IACA simulating tool ver 2.1 检查它)。融合对通常在 perf 中针对两条指令中的一个 IP 报告。
标签: linux performance caching perf