3

以下是 perf Linux 分析器对 gcc 生成的 C++ 代码的输出。我在一个循环中计算 (a[i]+b[i])^c[i],从 i=n 向下直到循环存在于 i=-1。这是迄今为止我的程序中最热的循环,可以运行数小时或数天。

如果我正确理解了这个输出,那么 perf 会告诉我这个函数中 57% 的时间都花在了从 rdx 寄存器中减去 8 上。这似乎不太可能,因为从上面三行的 rcx 寄存器中减去 1 只需要 0.99% 的时间。我想我一定错过了什么。这些数字的解释是什么?前面指令的时间是否以某种方式不公平地被计入减法?

    3.64 :          484388:       mov    0x0(%rbp,%rdx,1),%rax
    0.64 :          48438d:       add    (%rbx,%rdx,1),%rax
    0.99 :          484391:       sub    $0x1,%rcx
    3.60 :          484395:       xor    (%rdi,%rdx,1),%rax
   57.13 :          484399:       sub    $0x8,%rdx
    0.22 :          48439d:       or     %rax,%rsi
    4.23 :          4843a0:       cmp    $0xffffffffffffffff,%rcx
    0.00 :          4843a4:       jne    484388

我通过执行“perf record ./myprogram”得到这些数字,然后在同一目录中执行“perf report”,然后我浏览到这个程序集。

4

1 回答 1

2

我在perf wiki上找到了这个:

基于中断的采样在现代处理器上引入了滑动。这意味着存储在每个样本中的指令指针指定了程序被中断以处理PMU中断的位置,而不是计数器实际溢出的位置,即采样周期结束时的位置。在某些情况下,如果有分支,这两个点之间的距离可能是几十条指令或更多。当程序无法取得进展时,这两个位置确实是相同的。因此,在解释配置文件时必须小心。

这可能是解释。不幸的是,wiki 没有说明如何确定这是否确实是问题或如何纠正此问题。

于 2012-10-26T17:20:05.197 回答