性能分析利器之perf浅析
源:http://walkerdu.com/2018/09/13/perf-event/作为服务器后台开发,不仅仅要写业务逻辑,后台意味着高并发,稳定性,当你写了很多逻辑,发现性能有问题的时候,也要学会性能分析,进行性能优化, 也许你会接触很多性能分析工具:valgrind,gperftools,gprof, oprofile, 有时间慢慢一一介绍,在学习perf的过程中,也学习和加深了很多之前的知识,本文抛砖引玉,希望能帮助大家了解一些性能分析更深的一些东西 。
1. perf简介perf是一款linux内置的性能分析工具,随着内核发布,也被称为perf_events, perf tools, PCL(Performance Counters for Linux), 发布于Linux kernel version 2.6.31, perf是怎么工作的呢?perf如何使用?本文是来介绍一下 。
perf官方wiki的介绍是:Linux profiling with performance counters
Perf可以解决高级性能和故障排除,它可以分析(当然目前我也只是用来进行cpu性能分析):
- 为什么内核消耗CPU高, 代码的位置在哪里?
- 什么代码引起了CPU 2级cache未命中?
- CPU是否消耗在内存I/O上?
- 哪些代码分配内存,分配了多少?
- 什么触发了TCP重传?
- 某个内核函数是否正在被调用,调用频率多少?
- 线程释放CPU的原因?
- Hardware Events: CPU中的寄存器含有performance counters(性能计数器),用来统计 Hardware event,例如 cpu-cycles、instructions executed 、cache-misses、branch mispredicted等 。这些event构成了应用程序profiling的基础 。
- Software Events: 基于内核计数器的低优先级events,例如, CPU migrations(处理器迁移次数), minor faults(soft page faults), major faults(hard page faults).
- Tracepoints: 是散落在内核源代码中的一些 hook,用来调用probe函数,开启后,它们便可以在特定的代码被运行到时被触发,这一特性可以被各种 trace/debug 工具所使用 。Perf 就是该特性的用户之一 。假如您想知道在应用程序运行期间,内核内存管理模块的行为,便可以利用潜伏在 slab 分配器中的 tracepoint 。当内核运行到这些 tracepoint 时,便会通知 perf 。
- Dynamic Tracing: probe函数(探针or探测函数),kprobe(kernel probe)内核态探针,用来创建和管理内核代码中的探测点 。Uprobes,user-probe,用户态探针,用来对用户态应用程序进行探测点的创建和管理,关于kprobe和uprobe可参考对应的内核文档
- perf使用的event来源,如下图:来源:brendangregg

文章插图
3. 安装两种安装方式
- 通过包管理进行安装,perf工具在 linux-tools-common工具包里,通过包管理软件安装的时候还需要依赖linux-tools-kernelversion包
- 源码编译:找到对应内核版本的源码包,在tools/perf目录下进行编译
4.1 符号表
应用程序的符号表,用来将逻辑地址翻译成对应的函数和变量名,这样才能被程序员阅读和分析,没有符号表,profile的结果都是一些16进制的逻辑地址:
如下是perf report分析sshd进程的堆栈调用情况(来自brendangregg):

文章插图
对于通过软件包安装的程序,通常都会有dubug package(-dbgsym)即带有符号表信息的程序,如果是源码安装的就需要编译时开启debug选项 。
通过使用openssh-server-dbgsym and libc6-dbgsym,sshd的perf report分析结果如下:

文章插图
4.2 栈回溯(栈展开)
我们经常在编译的时候会开启frame pointers优化选项,即优化掉函数栈帧rbp,省略掉frame pointer是编译器一个很烂的优化,它会破坏debug, 更烂的是省略frame pointer一般是编译器默认的优化选项 。
没有frame pointer会使perf 无法获取完整的调用栈,如下示例:

文章插图
例如上面代码正常不开启优化的编译,进行profile是可以看到call graph的,如下:

文章插图
如果编译时开启-fomit-frame-pointer(这里因为测试代码简单,直接开优化的话就优化没了),就无法获取到call graph
推荐阅读
- wireshark网络小故障分析定位
- 笔记本|入门性能可战GTX 1650!用户买不到 Intel Arc显卡本着急了:官方回应
- 详解mysql数据库double write原理、性能影响及相关参数
- centos安装awstats分析apache的日志
- CPU处理器|闲鱼惊现剪角CPU 称502+沙子就能补上 网友:只剩3/4性能了
- 东瀛煮茶利器,日本老铁壶
- 茶叶品牌走高端奢侈品路线分析
- web服务器遭受黑客攻击时的日志分析及排查
- MySQL 多源复制场景分析
- 茶馆的经营模式分析,满足顾客的个性化需求