首发|RustMagazine

简介
程序的性能分析是一个很广很深的话题,有各种各样的工具来对不同的指标进行测试分析。本文主要介绍如何用profiling工具对Rust程序进行On-CPU和Off-CPU的性能分析,以及如何绘制火焰图对结果测试进行可视化处理。
On-CPU性能分析
On-CPU的性能分析为了找出占用CPU时间多的任务或者函数,进而找出程序的性能瓶颈。这里主要介绍perf工具,perf是Linux提供的命令,也叫perf_events,它属于Linux kernel,在tools/perf目录下。perf提供了强大的功能包括监测CPU performance counters, tracepoints, kprobes和 uprobes等。这里我们使用perf的CPU profiling功能。由于perf会拿到系统的信息,所以运行需要root权限。perf做On-CPU性能分析的原理是以一个指定的频率对CPU进行采样,进而拿到正在CPU上运行的指令乃至整个函数调用栈的快照,最后对采样的数据分析,比如说在100次采样中有20次在运行A指令或者A函数,那么perf就会认为A函数的CPU使用率为20%。
下面我们使用一个简单的程序来展示如何用perf来进行On-CPU的性能分析,需要使用debug编译,程序如下:
fn test2() {
for _ in 0..200000 {
()
}
}
fn test1() {
for _ in 0..100000 {
()
}
test2();
}
fn main() {
for _ in 0..10 {
test1();
}
}
我们在test1()函数和test2()函数中分别加入了一个段循环来消耗CPU资源,在test2()中我们循环了200000次是在test1()中的两倍。我们使用如下perf命令来做CPU profiling:
$ sudo perf record --call-graph=dwarf ./target/debug/mytest
采样的数据默认会存到perf.data文件中。参数--call-graph的目的是开启函数调用栈的记录,这样在profiling的结果中可以打印出完整的函数调用栈。目前perf支持fp(frame pointer), dwarf(DWARF's CFI - Call Frame Information)和lbr(Hardware Last Branch Record facility)三种方式来获取函数调用栈。稍后我们会简单介绍fp和dwarf的原理。由于Rust编译器默认生成了dwarf格式的调试信息,我们可以直接使用--call-graph=dwarf。我们可以使用如下命令来读取profiling的结果:
$ sudo perf report --stdio
这个命令会默认读取perf.data中的数据并格式化输出。命令的输出如下,因为输出很长,部分无关信息被省略掉,
# Children Self Command Shared Object Symbol
# ........ ........ ....... ................. .........................................................................................................
#
77.57% 0.00% mytest

本文详细介绍了如何使用perf工具对Rust程序进行On-CPU性能分析,通过火焰图进行结果可视化,并探讨了Off-CPU性能分析的重要性,展示了如何利用eBPF的offcputime-bpfcc工具进行Off-CPU分析,最后呈现了Off-CPU火焰图。通过对On-CPU和Off-CPU的综合分析,可以全面了解程序的性能瓶颈。
最低0.47元/天 解锁文章
2193

被折叠的 条评论
为什么被折叠?



