perf
Perf主要基于性能事件的采集和分析,有两种采集方法:
基于硬件的采集方法,此种方法需要采用CPU中的PMU(performance monitoring unit)部件,在特定的条件下探测性能事件是否发生以及发生的次数。每次的特定的性能时事件发生后,PMU的计数器便+1,当溢出时,会触发performance monitoring interrupt(PMI),内核在PMI 中断的处理函数中保存PMC的计数值,触发中断时的指令地址(Register IP:Instruction Pointer),当前时间戳以及当前进程的PID,TID,comm 等信息。我们把这些信息统称为一个采样(sample)。内核会将收集到的sample 放入用于跟用户空间通信的Ring Buffer。用户空间里的perf 分析程序采用mmap 机制从ring buffer 中读入采样,并对其解析。
基于软件的采集方法,需要将代码内置于kernel,分布在各个功能模块中,统计和操作系统相关性能事件。内核在其源代码中有许多的tracepoint,这些tracepoint一旦使能,程序若执行到这些特定的点,便会通知perf,perf将tracepoint产生的事件记录下来,生成报告。
https://www.cnblogs.com/arnoldlu/p/6241297.html 非常详细的命令介绍和使用
perf --help之后可以看到perf的二级命令。
| 序号 | 命令 | 作用 |
|---|---|---|
| 1 | annotate | 解析perf record生成的perf.data文件,显示被注释的代码。 |
| 2 | archive | 根据数据文件记录的build-id,将所有被采样到的elf文件打包。利用此压缩包,可以再任何机器上分析数据文件中记录的采样数据。 |
| 3 | bench | perf中内置的benchmark,目前包括两套针对调度器和内存管理子系统的benchmark。 |
| 4 | buildid-cache | 管理perf的buildid缓存,每个elf文件都有一个独一无二的buildid。buildid被perf用来关联性能数据与elf文件。 |
| 5 | buildid-list | 列出数据文件中记录的所有buildid。 |
| 6 | diff | 对比两个数据文件的差异。能够给出每个符号(函数)在热点分析上的具体差异。 |
| 7 | evlist | 列出数据文件perf.data中所有性能事件。 |
| 8 | inject | 该工具读取perf record工具记录的事件流,并将其定向到标准输出。在被分析代码中的任何一点,都可以向事件流中注入其它事件。 |
| 9 | kmem | 针对内核内存(slab)子系统进行追踪测量的工具 |
| 10 | kvm | 用来追踪测试运行在KVM虚拟机上的Guest OS。 |
| 11 | list | 列出当前系统支持的所有性能事件。包括硬件性能事件、软件性能事件以及检查点。 |
| 12 | lock | 分析内核中的锁信息,包括锁的争用情况,等待延迟等。 |
| 13 | mem | 内存存取情况 |
| 14 | record | 收集采样信息,并将其记录在数据文件中。随后可通过其它工具对数据文件进行分析。 |
| 15 | report | 读取perf record创建的数据文件,并给出热点分析结果。 |
| 16 | sched | 针对调度器子系统的分析工具。 |
| 17 | script | 执行perl或python写的功能扩展脚本、生成脚本框架、读取数据文件中的数据信息等。 |
| 18 | stat | 执行某个命令,收集特定进程的性能概况,包括CPI、Cache丢失率等。 |
| 19 | test | perf对当前软硬件平台进行健全性测试,可用此工具测试当前的软硬件平台是否能支持perf的所有功能。 |
| 20 | timechart | 针对测试期间系统行为进行可视化的工具 |
| 21 | top | 类似于linux的top命令,对系统性能进行实时分析。 |
| 22 | trace | 关于syscall的工具。 |
| 23 | probe | 用于定义动态检查点。 |
perf list
列出所有perf可以采样的点,总体分为三类:
Hardware Event 是由 PMU 硬件产生的事件,比如 cache 命中,当您需要了解程序对硬件特性的使用情况时,便需要对这些事件进行采样;
Software Event 是内核软件产生的事件,比如进程切换,tick 数等 ;
Tracepoint event 是内核中的静态 tracepoint 所触发的事件,这些 tracepoint 用来判断程序运行期间内核的行为细节,比如 slab 分配器的分配次数等。
perf stat
perf stat progName
查看进程整体的一些统计数据

Task-clock-msecs:CPU 利用率,该值高,说明程序的多数时间花费在 CPU 计算上而非 IO。
Context-switches:进程切换次数,记录了程序运行过程中发生了多少次进程切换,频繁的进程切换是应该避免的。
CPU-migrations:表示进程 t1 运行过程中发生了多少次 CPU 迁移,即被调度器从一个 CPU 转移到另外一个 CPU 上运行。
Cycles:处理器时钟,一条机器指令可能需要多个 cycles,
Instructions: 机器指令数目。
IPC:是 Instructions/Cycles 的比值,该值越大越好,说明程序充分利用了处理器的特性。
Cache-references: cache 命中的次数
Cache-misses: cache 失效的次数。
perf top
类似于top命令,显示系统中所有进程当前的性能情况,用于观察当前系统的性能情况,可以找出对系统性能影响最大的进程。
perf top -e eventname
-e选项指定关注当前系统内的某个指标,该指标时perf list中的一项。
perf record 收集采样信息,并将其记录在数据文件中。

perf record -e eventname progname
perf report // 读取perf record创建的数据文件,并给出热点分析结果。
perf record可以按照某个事件,记录程序中每个函数的该指标统计信息

这里看的是单个函数的各种指标信息,但有时候看不出真正需要调优的函数;有时候会发现一些肯定要用的函数的指标偏高,例如STL容器的一些成员方法,但我们一般不需要去优化这类函数,我们应当去寻找到底是什么函数多次的调用了这些函数,对这些函数进行调优,便能提高程序的性能
perf record -g -e eventname progname
perf report -g // -g calling graph
用calling graph显示每个函数的调用,配合指标信息来看便可指定应该减少哪个函数的调用可以提高性能

perf probe 自定义探测点
tracepoint是静态检查点,是内核代码设计了的检查位置,如果我们想自己添加新的检查点,可以使用perf probe,自定义动态tracepoint.

上图的perf probe 指定在shcedule函数的第十二行创建一个动态tracepoint,当执行到这里里,perf便会有相应的统计信息.