目 录CONTENT

文章目录

性能分析工具 perf

TalentQ
2025-08-29 / 0 评论 / 0 点赞 / 5 阅读 / 0 字

1 perf 简介

perf是 Linux 内核自带的性能分析工具,基于内核的 Performance Monitoring Unit(PMU)实现。它能够收集CPU、缓存、分支预测等硬件事件,以及内核和用户空间的各种软件事件。perf 支持采样(Sampling)、统计(Counting)、调用栈追踪(Call Graph)等多种模式。适用于性能瓶颈定位、热点函数分析、系统级调优等多种场景。

1.1 主要功能

  • 统计性能事件(CPU使用率、缓存命中率等)

  • 采样函数调用栈,定位热点代码

  • 分析系统性能(进程、线程、内核模块等)

  • 生成可视化报告

1.2 工作原理

perf 通过内核暴露的 perf_event_open 系统调用,与硬件PMU或内核 tracepoint 交互,收集事件数据。核心流程如下:

  1. 用户启动 perf ,指定监控事件和目标对象;

  2. perf 设置事件监控,内核开始统计或采样;

  3. 事件触发时,相关数据被记录到内核缓冲区;

  4. perf 工具从内核读取数据,生成报告或可视化结果。

1.3 核心概念

事件(Event)。分为硬件事件(cycles、instructions、cache-misses等)、软件事件(page-faults、context-switches等)、自定义 tracepoint。

统计(Counting)。记录事件发生的总次数,时和整体性能评估。

采样(Sampling)。定期或按事件阈值采集程序状态,用于热点定位。

调用栈(Call Graph)。perf 支持内核和用户空间的调用栈采集,帮助分析函数间的调用关系和耗时分布。

PMU(Performance Monitoring Unit)。现代CPU内置PMU,能高效统计低级硬件指令。perf通过PMU获取这些数据。

2 安装

先检查当前系统是否有 perf 工具:perf --version

如果没有则运行指令安装:

sudo apt update
sudo apt install linux-tools-common linux-tools-$(uname -r)

3 使用

3.1 perf stat —— 性能事件统计

统计程序运行期间的各种事件,时和宏观性能对比。

示例:

sudo perf stat -e cycles,instructions,cache-misses ./your_program
  • -e:指定要统计的事件

    • cycles:CPU时钟周期数

    • instructions:执行的指令数

    • cache-misses:缓存未命中次数

3.2 perf record/report —— 采样/报告

采样(record):采集程序运行时的采样数据(如PC、调用栈)。

报告(report):对采样数据进行分析,展示热点函数、调用栈等信息。

测试代码:

#include <vector>
#include <iostream>

int ComputeSum(const std::vector<int>& data) {
  int sum = 0;
  for (int v : data) {
    sum += v;
  }
  return sum;
}

int main() {
  std::vector<int> numbers(10000000, 1);
  std::cout << "Sum: " << ComputeSum(numbers) << std::endl;
  return 0;
}

编译并采样:

g++ -g -O2 test-demo.cc -o test-demo
sudo perf record ./test-demo
sudo perf report

报告内容:

  • %:该符号在采样中的比例

  • Symbol:函数名

  • Shared Pbject:代码所在文件/库

分析长期运行的服务进程:

sudo perf record -p <pid> -g

sudo perf report

全系统采样,适合排查系统级性能瓶颈:

sudo perf record -a -g

sudo perf report

3.3 perf top —— 实时热点分析

实时显示当前系统或进程的热点函数

3.4 函数调用栈分析

sudo perf record -g ./your_program
sudo perf report

-g:开启调用栈采集,报告中可以查看函数之间的调用路径

-F <NUMBER>:指定采集频率,默认频率为 4000Hz

-p <PID>:指定进程

-t <TID>:指定线程

4 可视化 —— 火焰图(Flame Graph)

火焰图基于采样调用栈(如perf record -g采集的数据),统计各个调用路径出现的次数。每条“火焰”宽度表示耗时,层级表示调用链。

对某个程序采样:

sudo perf record -F 99 -g ./your_program
// -F 99 设置采样频率为99Hz
// -g 采集调用栈(Call Graph)

对整个系统采样:

sudo perf record -F 99 -a -g
// -a 表示全系统采样

采样后会生成 perf.data 文件,包含所有采样点的调用栈信息。

4.1 安装 FlameGraph 工具

FlameGraph 是一套Perl脚本,需要从github上克隆到本地。

下载:

git clone https://github.com/brendangregg/FlameGraph.git

4.2 火焰图生成步骤

1 使用 perf 采集调用栈数据

sudo perf record -F 99 -g ./your_program

2 生成脚本数据

sudo perf script -i /path/to/perf.data > out.perl

3 折叠调用栈

进入 FlameGraph 目录:

4 生成 SVG 火焰图

./flamegraph.pl out.folded > flamegraph.svg

步骤2,3,4可以使用管道连接:

sudo perf script -i /path/to/perf.data | ./stackcollapse-perf.pl | ./flamegraph.pl > flamegraph.svg

0

评论区