测试 使用 perf 进行性能分析时如何获取准确的调用栈

测试 使用 perf 进行性能分析时如何获取准确的调用栈

ifonly · 2020年02月27日 · 101 次阅读

 目录

perf 是 Linux 下重要的性能分析工具,perf 可以通过采样获取很多性能指标,其中最常用的是获取 CPU Cycles,即程序各部分代码运行所需的时间,进而确定性能瓶颈在哪。不过在实际使用过程中发现,简单的使用perf record -g 获取到的调用栈是有问题的,存在大量 [Unknown] 函数,从 perf report 的结果来看这些部分对应地址大部分都是非法地址,且生成的火焰图中存在很多明显与代码矛盾的调用关系。

最初怀疑是优化级别的问题,然而尝试使用 Og 或 O0 优化依然存在此问题,仔细阅读 perf record 的手册后发现,perf 同时支持 3 种栈回溯方式:fpdwarflbr,可以通过 --call-graph 参数指定,而 -g 就相当于 --call-graph fp.

栈回溯方式

fp 就是 Frame Pointer,即 x86 中的 EBP 寄存器,fp 指向当前栈帧栈底地址,此地址保存着上一栈帧的 EBP 值,具体可参考此文章的介绍,根据 fp 就可以逐级回溯调用栈。然而这一特性是会被优化掉的,而且这还是 GCC 的默认行为,在不手动指定 -fno-omit-frame-pointer 时默认都会进行此优化,此时 EBP 被当作一般的通用寄存器使用,以此为依据进行栈回溯显然是错误的。不过尝试指定 -fno-omit-frame-pointer 后依然没法获取到正确的调用栈,根据 GCC 手册的说明,指定了此选项后也并不保证所有函数调用都会使用 fp…… 看来只有放弃使用 fp 进行回溯了。

dwarf 是一种调试文件格式,GCC 编译时附加的 -g 参数生成的就是 dwarf 格式的调试信息,其中包括了栈回溯所需的全部信息,使用 libunwind 即可展开这些信息。dwarf 的进一步介绍可参考 “关于 DWARF”,值得一提的是,GDB 进行栈回溯时使用的正是 dwarf 调试信息。实际测试表明使用 dwarf 可以很好的获取到准确的调用栈。

最后 perf 还支持通过 lbr 获取调用栈,lbr 即 Last Branch Records,是较新的 Intel CPU 中提供的一组硬件寄存器,其作用是记录之前若干次分支跳转的地址,主要目的就是用来支持 perf 这类性能分析工具,其详细说明可参考 “An introduction to last branch records” & “Advanced usage of last branch records”。此方法是性能与准确性最高的手段,然而它存在一个很大的局限性,由于硬件 Ring Buffer 寄存器的大小是有限的,lbr 能记录的栈深度也是有限的,具体值取决于特定 CPU 实现,一般就是 32 层,若超过此限制会得到错误的调用栈。

测试

实际测试下以上 3 种栈回溯方式得到的结果,测试程序是一个调用深度为 50 的简单程序,从 f0() 依次调用至 f50()

--call-graph fp

--call-graph lbr

--call-graph dwarf

可以看到,的确只有 dwarf 获取到了正确的调用栈。

总结

优点缺点
fpNone1. 默认 fp 被优化掉了根本不可用。
lbr1. 高效准确1. 需要较新的 Intel CPU 才有此功能;2. 能记录的调用栈深度有限。
dwarf1. 准确1. 开销相对较大;2. 需要编译时附加了调试信息。
### 如何进行内存性能测试 #### 使用工具和方法概述 为了进行全面的内存性能测试,可以采用多种方式来评估系统的内存使用情况及其效率。一种简单的方法是在Linux环境中通过编写C程序并编译运行该程序以消耗指定数量的内存量[^1]。 ```bash gcc mem.c -o mem.out ./mem.out 100 & ``` 上述命令会创建一个名为`mem.out`的可执行文件,并启动它作为后台进程,此过程将分配大约100 MB的RAM给这个应用程序实例。要终止占用资源的操作只需杀死相应的进程即可。 对于更深入细致地分析系统内部行为以及定位具体函数调用上的瓶颈位置,则可能需要用到像`perf`这样的性能剖析工具[^3]: - **事件计数模式**:仅统计特定类型的硬件或软件事件的发生次数; - **采样模式**:定期记录下当前正在被执行指令的位置信息以及其他关联数据; 这两种工作模式能够帮助识别出哪些部分占用了过多的间片或是触发了大量的页面错误等异常状况。 另外,在虚拟化平台上开展此类实验需要注意一些特殊参数设置的影响范围[^4],比如开启大页支持可能会改变默认情况下处理匿名映射的方式从而影响到最终测量的结果准确性。 #### 实际操作指南 当准备就绪之后就可以按照如下步骤来进行实际测试了: - 编写一段简单的代码用于请求固定大小的工作集; - 将其编译链接成独立的应用二进制镜像; - 执行生成的目标文件并向其中传递期望使用的字节数目作为输入参数; - 利用操作系统自带的任务管理器或者其他第三方库监控整个过程中涉及的各项指标变化趋势; - 结束测试后记得清理残留的数据结构防止干扰后续其他任务正常运作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值