Ror*_*ory 2 optimization performance performance-testing perf
我perf
曾经用perf record ./application
. perf report
向我展示了有关它的各种事情。如何显示运行应用程序所需的总时间以及运行特定“符号”/功能的总时间?perf 似乎经常显示百分比,但我想要原始时间,并且它想要“包容性”时间,即包括孩子。
Ubuntu Linux 18.04 上的 perf v4.15.18
perf 是统计(采样)分析器(在默认perf record
模式下),这意味着它在函数进入和退出时没有精确的时间戳(精确数据需要跟踪)。Perf 要求操作系统内核每秒生成数千次中断(如果-e cycles
支持的话,硬件 PMU 为 4 kHz,软件事件更少-e cpu-clock
)。程序执行的每次中断都被记录为样本,其中包含EIP(当前指令指针)、pid(进程/线程id)、当前时间的时间戳。当程序运行几秒钟时,将会有数千个样本,并且perf report
可以根据它们生成直方图:程序代码的哪些部分(哪些函数)比其他部分执行得更频繁。您将大致了解某些函数确实占用了程序执行时间的 30% 左右,而其他函数则占用了 5%。
perf 报告不计算总的程序执行时间(它可以通过比较第一个和最后一个样本的时间戳来估计它,但如果存在关闭 CPU 周期,则它是不准确的)。但它确实估计了事件总数(它打印在交互式 TUI 的第一行中,并在文本输出中列出):
$ perf report |grep approx
# Samples: 1K of event 'cycles'
# Event count (approx.): 844373507
Run Code Online (Sandbox Code Playgroud)
有一个perf report -n
选项可以在百分比列旁边添加“样本数”列。
Samples: 1K of event 'cycles', Event count (approx.): 861416907
Overhead Samples Command Shared Object Symbol
42.36% 576 bc bc [.] _bc_rec_mul
37.49% 510 bc bc [.] _bc_shift_addsub.isra.3
14.90% 202 bc bc [.] _bc_do_sub
0.89% 12 bc bc [.] bc_free_num
Run Code Online (Sandbox Code Playgroud)
但采样的时间间隔不同,并且不如计算的开销精确(每个样本可能具有不同的权重)。我建议您运行perf stat ./application
以获得应用程序的实际总运行时间和总硬件计数。当您的应用程序具有稳定的运行时间时会更好(perf stat -r 5 ./application
工具估计的变化为最后一列中的“+- 0.28%”)
要包含子函数,必须在每次中断时对堆栈跟踪进行采样。在默认模式下不对它们进行采样perf record
。-g
使用或选项打开此采样 --call-graph dwarf
:perf record -g ./application
或perf record --call-graph dwarf ./application
。在 Linux 中正确使用它来预装库或应用程序并不简单(因为大多数发行版都会从包中删除调试信息),但可以用于您自己使用调试信息编译的应用程序。默认值与要求所有代码都使用gcc选项编译-g
相同,非默认值更可靠。通过正确准备的程序和库、单线程应用程序以及足够长的堆栈大小示例(默认为 8KB,用 更改),应该显示大约 99% 的和函数(包括子函数)。--call-graph fp
-fno-omit-frame-pointer
--call-graph dwarf
--call-graph dwarf,65536
perf report
_start
main
bc 计算器编译为-fno-omit-frame-pointer
:
bc-no-omit-frame$ echo '3^123456%3' | perf record -g bc/bc
bc-no-omit-frame$ perf report
Samples: 1K of event 'cycles:uppp', Event count (approx.): 811063902
Children Self Command Shared Object Symbol
+ 98.33% 0.00% bc [unknown] [.] 0x771e258d4c544155
+ 98.33% 0.00% bc libc-2.27.so [.] __libc_start_main
+ 98.33% 0.00% bc bc [.] main
Run Code Online (Sandbox Code Playgroud)
带有矮调用图的 bc 计算器:
$ echo '3^123456%3' | perf record --call-graph dwarf bc/bc
$ perf report
Samples: 1K of event 'cycles:uppp', Event count (approx.): 898828479
Children Self Command Shared Object Symbol
+ 98.42% 0.00% bc bc [.] _start
+ 98.42% 0.00% bc libc-2.27.so [.] __libc_start_main
+ 98.42% 0.00% bc bc [.] main
Run Code Online (Sandbox Code Playgroud)
没有调试信息的 bc 在 (fp) 模式下 perf 的调用图处理不正确-g
(main 没有 99%):
$ cp bc/bc bc.strip
$ strip -d bc.strip
$ echo '3^123456%3' | perf record --call-graph fp ./bc.strip
Samples: 1K of event 'cycles:uppp', Event count (approx.): 841993392
Children Self Command Shared Object Symbol
+ 43.94% 43.94% bc.strip bc.strip [.] _bc_rec_mul
+ 39.73% 39.73% bc.strip bc.strip [.] _bc_shift_addsub.isra.3
+ 11.27% 11.27% bc.strip bc.strip [.] _bc_do_sub
+ 0.92% 0.92% bc.strip libc-2.27.so [.] malloc
Run Code Online (Sandbox Code Playgroud)
有时perf report --no-children
禁用对 self+children 开销的排序(将按“self”开销排序)很有用,例如,当未完全捕获调用图时。
归档时间: |
|
查看次数: |
1472 次 |
最近记录: |