以下是由gcc生成的C ++代码上的perf Linux profiler输出。我正在计算(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”,然后我浏览了这个程序集。
答案 0 :(得分:2)
我在perf wiki上找到了这个:
基于中断的采样引入了现代处理器的滑动。那 表示存储在每个样本中的指令指针 程序被中断以处理PMU的地方 中断,而不是计数器实际溢出的地方,即 它是在采样期结束时的地方。在某些情况下, 这两点之间的距离可能是几十个指令或 更多,如果有分支机构。当程序无法制作时 前进的进展,这两个地方确实相同。为了这 理由是,在解释档案时必须小心。
这可能是解释。不幸的是,wiki没有说明如何确定这是否确实是问题或如何解决这个问题。