主要的Perf和PIN分析差异

时间:2013-11-12 04:48:48

标签: linux profiling instrumentation perf

为了分析执行时间的某些属性,我打算在程序的单独执行中同时使用PerfPIN来获取我的所有信息。 PIN会给我指令混音,Perf会给我这些混音的硬件性能。作为一个完整性检查,我分析了以下命令行参数:

g++ hello_world.cpp -o hello

所以我的完整命令行输入如下:

perf stat -e cycles -e instructions g++ hello_world.cpp -o hello
pin -t icount.so -- g++ hello_world.cpp -o hello

在PIN命令中,为了这篇文章,我忽略了文件的所有路径内容。此外,除了默认的动态指令计数之外,我还更改了基本icount.so以记录指令混音。结果令人惊讶地不同

PIN Results:
Count 1180608
14->COND_BR: 295371
49->UNCOND_BR: 21869
//skipping all of the other instruction types for now

Perf Results:
       20,538,346 branches                                                    
       105,662,160 instructions              #    0.00  insns per cycle        

       0.072352035 seconds time elapsed

这应该通过具有大致相同的指令计数和大致相同的分支分布来作为健全性检查。 为什么动态指令计数会被 x100 的因子关闭?!我曾经有过一些噪音,但这有点多了。

此外,Perf的分支数量为20%,但PIN报告约为25%(这似乎也有点差异,但它可能只是大量指令计数失真的副作用)。

1 个答案:

答案 0 :(得分:1)

icount pintool 计算的内容与 instructions 性能事件之间存在显着差异,后者映射到现代英特尔处理器上的架构 Instructions Retired 硬件性能事件。我假设您使用的是 Intel 处理器。

  • pin 仅在指定 -follow_execv 命令行选项时注入子进程,如果 pintool 注册了回调函数来拦截进程创建,则回调返回 true。另一方面,perf 默认配置所有子进程。您可以使用 perf 选项告诉 -i 仅分析指定的进程。
  • perf,默认情况下,分析在用户模式和内核模式下发生的所有事件(如果 /proc/sys/kernel/perf_event_paranoid 小于 2)。 pin 仅支持在用户模式下进行分析。
  • icount pintool 以基本块粒度计数,它本质上是一个短的、单入口、单出口的指令序列。如果块中的指令导致异常,则块中的其余指令将不会被执行,但它们已经被计数。可以在不终止程序的情况下处理异常。 instructions 只计算退休时的指示。
  • 默认情况下,icount pintool 将 rep 前缀指令的每次迭代计为一条指令。 instructions 事件将带有 rep 前缀的指令计为一条指令,而不考虑迭代次数。
  • 在某些处理器上,instructions 事件可能会多计数或少计数。

由于前两个原因,instructions 事件计数可能更大。由于接下来的两个原因,icount pintool 指令计数可能更大。最后一个原因可能会导致不可预测的差异。由于 perf 计数大约是 icount 计数的 100 倍,因此很明显前两个因素在这种情况下占主导地位。

您可以通过将 -i 传递给 perf 来不分析孩子,将 :u 修饰符添加到 instructions 事件名称,从而获得两个工具来获得更接近的计数仅在用户模式下计数,并将 -reps 1 传递给 pin 以计算每条指令而不是每次迭代的 rep 前缀指令。

perf stat -i -e cycles,instructions:u g++ hello_world.cpp -o hello
pin -t icount.so -reps 1 -- g++ hello_world.cpp -o hello

您可以将 -i 传递给 perf,而不是将 -follow_execv 传递给 pin,如下所示:

pin -follow_execv -t icount.so -reps 1 -- g++ hello_world.cpp -o hello

通过这种方式,两个工具都将分析以指定进程(即正在运行的 g++)为根的整个进程层次结构。

我希望这些措施的计数非常接近,但它们仍然不会完全相同。