我目前正在使用以下参数调用 oprofile:
operf --callgraph --vmlinux /usr/lib/debug/boot/vmlinux-$(uname -r) <BINARY>
opreport -a -l <BINARY>
例如,输出为:
CPU: Core 2, speed 2e+06 MHz (estimated)
Counted CPU_CLK_UNHALTED events (Clock cycles when not halted) with a unit mask of 0x00 (Unhalted core cycles) count 90000
samples cum. samples % cum. % image name symbol name
12635 12635 27.7674 27.7674 libc-2.15.so __memset_sse2
9404 22039 20.6668 48.4342 vmlinux-3.5.0-21-generic get_page_from_freelist
4381 26420 9.6279 58.0621 vmlinux-3.5.0-21-generic native_flush_tlb_single
3684 30104 8.0962 66.1583 vmlinux-3.5.0-21-generic page_fault
701 30805 1.5406 67.6988 vmlinux-3.5.0-21-generic handle_pte_fault
您可以看到大部分时间都花在了__memset_sse2
其中,但我自己的代码应该优化哪一个并不明显。至少不是来自上面的输出。
在我的具体情况下,我能够通过使用某种穷人的探查器来快速定位问题的根源。我在调试器中运行程序,不时停止它并查看每个线程的调用堆栈。
是否可以直接从 oprofile 的输出中获得相同的结果?如果性能瓶颈不像我的示例那样明显,那么我使用的策略很可能会失败。
是否有一个选项可以忽略对外部函数的所有调用(例如,对内核或 libc),而只是将时间累积给调用者?例如:
void foo() {
// some expensive call to memset...
}
foo
在这里,我在分析输出的顶部看到会更有洞察力,而不是memset
.
(我试过opreport --exclude-dependent
但发现它没有帮助,因为它似乎只是跳过了输出中的外部函数。)