分类: LINUX
2016-04-18 10:16:18
一.Perf简介
1. 从2.6.31内核开始,linux内核自带了一个性能分析工具perf,能够进行函数级与指令级的热点查。
Perf是Linux kernel自带的系统性能优化工具。Perf的优势在于与Linux Kernel的紧密结合,它可以最先应用到加入Kernel的new feature。pef可以用于查看热点函数,查看cashe miss的比率,从而帮助开发者来优化程序性能
Perf是一个包含22种子工具的工具集,以下是最常用的5种:
perf-list :Perf-list用来查看perf所支持的性能事件,有软件的也有硬件的。
perf-stat
perf-top: perf top主要用于实时分析各个函数在某个性能事件上的热度,能够快速的定位热点函数,包括应用程序函数、
模块函数与内核函数,甚至能够定位到热点指令。默认的性能事件为cpu cycles。
perf-record
perf-report
为了能够使perf读到函数名,我们的目标程序必须具备符号表。如果读者在perf的分析结果中只看到一串地址,而没有对应的函数名时,通常是由于在编译时利用strip删除了ELF文件中的符号表。建议读者在性能分析阶段,保留程序中的symbol table,debug info等信息。
CPU周期(cpu-cycles)是默认的性能事件,所谓的CPU周期是指CPU所能识别的最小时间单元,通常为亿分之几秒,
是CPU执行最简单的指令时所需要的时间,例如读取寄存器中的内容,也叫做clock tick。
2. 编译
以编译powerpc单板为例,编译perf工具方法如下
root@localhost perf]# cd kernel/linux/linux-3.10.55-cgel/kernel-version/cgel5.0/linux/tools/perf [root@localhost perf]# make ARCH=powerpc CROSS_COMPILE=/opt/ ppc_gcc4.8.2_glibc2.18.0_multi/bin/ppc64_e5500-hardfloat-linux-gnu- |
编译完成后,会在perf目录下生成可执行文件:perf,把该perf拷贝到目标板上运行即可。
3.perf使用方法;
3.1 perf stat
# perf stat -p 2872 ^C Performance counter stats for process id '2872':
4595.253120 task-clock # 0.180 CPUs utilized 37075 context-switches # 0.008 M/sec 1989 cpu-migrations # 0.433 K/sec 61107 page-faults # 0.013 M/sec 5406113059 cycles # 1.176 GHz [66.89%] 2164652068 stalled-cycles-frontend # 40.04% frontend cycles idle [68.12%] 1332765533 stalled-cycles-backend # 24.65% backend cycles idle [68.44%] 2703056624 instructions # 0.50 insns per cycle # 0.80 stalled cycles per insn [69.41%] 415878687 branches # 90.502 M/sec [67.33%] 48829719 branch-misses # 11.74% of all branches [64.96%]
25.543519168 seconds time elapsed
# |
缺省情况下,除了 task-clock-msecs 之外,perf stat 还给出了其他几个最常用的统计信息:
Task-clock-msecs:CPU 利用率,该值高,说明程序的多数时间花费在 CPU 计算上而非 IO。
Context-switches:进程切换次数,记录了程序运行过程中发生了多少次进程切换,频繁的进程切换是应该避免的。
Cache-misses:程序运行过程中总体的 cache 利用情况,如果该值过高,说明程序的 cache 利用不好
CPU-migrations:表示进程 t1 运行过程中发生了多少次 CPU 迁移,即被调度器从一个 CPU 转移到另外一个 CPU 上运行。
Cycles:处理器时钟,一条机器指令可能需要多个 cycles,
Instructions: 机器指令数目。
IPC:是 Instructions/Cycles 的比值,该值越大越好,说明程序充分利用了处理器的特性。
Cache-references: cache 命中的次数
Cache-misses: cache 失效的次数。
通过指定 -e 选项,您可以改变 perf stat 的缺省事件 ( 关于事件,在上一小节已经说明,可以通过 perf list 来查看 )。假如您已经有很多的调优经验,可能会使用 -e 选项来查看您所感兴趣的特殊的事件。
3.2查看单个进程各个函数cpu使用率
perf top -e cycles -p 3352 |
3.3使用perf record 记录:
perf record -e cpu-clock -p 进程号 perf report
|
3.4统计进程里最耗时函数
perf record -e cycles –g -p 进程号 perf report
|
perf record -a -F 1000 sleep 5
|
其中-F 1000是指定采样频率为1000次/秒
Sleep 5 指采样5秒
perf stat -e 'sched:*' -p 28135 sleep 5 |
统计5秒内28135进程调度情况
附录:
Symbols
perf_events, like other debug tools, needs symbol information (symbols). These are used to translate memory addresses into function and variable names, so that they can be read by us humans. Without symbols, you'll see hexadecimal numbers representing the memory addresses profiled.
The following perf report output shows stack traces, however, only hexadecimal numbers can be seen:
57.14% sshd libc-2.15.so [.] connect
|
--- connect
|
|--25.00%-- 0x7ff3c1cddf29
|
|--25.00%-- 0x7ff3bfe82761
| 0x7ff3bfe82b7c
|
|--25.00%-- 0x7ff3bfe82dfc
--25.00%-- [...]
If the software was added by packages, you may find debug packages (often "-dbgsym") which provide the symbols. Sometimes perf report will tell you to install these, eg: "no symbols found in /bin/dd, maybe install a debug package?".
Here's the same perf report output seen earlier, after adding openssh-server-dbgsym and libc6-dbgsym (this is on ubuntu 12.04):
57.14% sshd libc-2.15.so [.] __GI___connect_internal
|
--- __GI___connect_internal
|
|--25.00%-- add_one_listen_addr.isra.0
|
|--25.00%-- __nscd_get_mapping
| __nscd_get_map_ref
|
|--25.00%-- __nscd_open_socket
--25.00%-- [...]
I find it useful to add both libc6-dbgsym and coreutils-dbgsym, to provide some symbol coverage of user-level OS codepaths.
Another way to get symbols is to compile the software yourself. For example, I just compiled node (Node.js):
# file node-v0.10.28/out/Release/node
node-v0.10.28/out/Release/node: ELF 64-bit LSB executable, ... not stripped
This has not been stripped, so I can profile node and see more than just hex. If the result is stripped, configure your build system not to run strip(1) on the output binaries.
Kernel-level symbols are in the kernel debuginfo package, or when the kernel is compiled with CONFIG_KALLSYMS.