Ubuntu 系统下性能剖析工具: perf

perf 是内置于 Linux 内核源码树中的性能剖析(profiling)工具。

它基于事件采样原理,以性能事件为基础,支持针对处理器相关性能指标与操作系统相关性能指标的性能剖析。常用于性能瓶颈的查找与热点代码的定位。


1. 安装 perf

在大多数 Linux 发行版中,perf 工具包含在 linux-tools 包中。可以通过包管理器安装:

  • Debian/Ubuntu:
bash 复制代码
sudo apt-get install linux-tools-common linux-tools-generic
  • Red Hat/CentOS:
bash 复制代码
sudo yum install perf
2. 基本使用
列出可用事件

列出所有可用的性能事件(包括硬件和软件事件):

bash 复制代码
perf list
记录性能数据

记录目标程序的性能数据。例如,以99Hz频率对所有CPU采样并记录调用栈信息6秒:

bash 复制代码
perf record -g -a -F 99 sleep 6

可以指定特定事件类型来分析,如CPU时钟周期、缓存命中等:

bash 复制代码
perf record -e cpu-clock -a sleep 6

跟踪点用于跟踪系统调用等预定义事件:

bash 复制代码
perf record -e 'syscalls:sys_enter_*' -a sleep 6

perf record 的可选参数

参数 描述 示例 备注
-e 选择性能事件。可以是 CPU 周期、缓存未命中等。使用 perf list 命令来查看所有可用的事件。 perf record -e cpu-clock ./your_program 适用于指定要监控的性能事件类型
-a 记录整个系统的性能数据,而不仅仅是一个进程。这对于分析系统级的性能问题非常有用。 perf record -a sleep 6 允许对整个系统的性能进行剖析
-p <pid> 记录指定进程的性能数据。只关注某一个特定进程。 perf record -p 12345 sleep 6 <pid> 是目标进程的进程ID
-t <tid> 记录指定线程的性能数据。用于分析多线程程序中某个特定线程的性能。 perf record -t 12345 sleep 6 <tid> 是目标线程的线程ID
-o <file> 指定输出文件名。默认情况下,perf 会将数据保存在当前目录下的 perf.data 文件中。 perf record -o my_output.data ./your_program 自定义性能数据的存储位置
-g 记录函数调用关系(调用栈)。这对于分析程序中函数调用和热点非常有帮助。 perf record -g ./your_program 提供了函数调用链的信息,有助于理解代码执行路径
-c <count> 设置事件的采样周期。例如,每发生1000次事件采样一次。 perf record -c 1000 ./your_program 控制基于计数器的采样频率
-F <frequency> 设置事件的采样频率。例如,每秒采样1000次。 perf record -F 1000 ./your_program 控制基于时间的采样频率

使用建议

  • 系统级分析 :如果你希望对整个系统进行性能分析,可以使用 -a 参数。
  • 特定进程/线程分析 :对于专注于分析特定的进程或线程的情况,分别使用 -p-t 参数。
  • 函数调用关系 :当需要理解程序的函数调用关系,尤其是在定位性能热点时,-g 参数非常重要。
  • 简单开始 :在实际使用中,一开始可以只用 perf record ./your_program 来进行简单的性能记录,然后根据具体需求添加不同的参数。
分析性能数据

使用 perf report 分析记录的数据,默认读取当前目录下的 perf.data 文件。可使用 -i 指定其他文件。


3. 使用示例

一个简单的 C++ 程序比较 push_backemplace_back 的性能差异。编译和运行后,使用 perf 工具进行性能分析。

由于 emplace_back 避免了对象的复制,所以在这种情况下,它会显示出更好的性能。

  • push_back 的性能热点

  • ComplexObject::ComplexObject(int) 被频繁调用,且每次调用都伴随着内存分配和初始化。

  • 构造函数和析构函数的调用占用了大量 CPU 时间(例如,ComplexObject::ComplexObject(int) 占比 4.12%,ComplexObject::~ComplexObject() 占比 2.94%)。

  • std::vector::push_back 涉及到更多的复制或移动操作,这可能导致更高的开销。

  • ComplexObject::ComplexObject(int) 占比 4.71%,表示构造函数被频繁调用。
  • std::vector<ComplexObject, std::allocator<ComplexObject> >::~vector() 占比 3.53%,表示析构函数也被频繁调用。
  • void std::vector<ComplexObject, std::allocator<ComplexObject>>::push_back(ComplexObject const&) 占比 2.94%,这可能涉及到对象的复制或移动操作。

emplace_back 的性能优势

  • emplace_back 直接在向量中构造对象,减少了临时对象的创建和销毁,从而降低了构造函数和析构函数的调用次数。
  • 这种方式避免了不必要的复制或移动操作,因此通常会更快。
4. 其他功能
  • 实时性能监控 : 使用 perf top 查看实时性能热点。
  • 注解(Annotate): 对特定函数或代码行进行源代码级别的性能分析。
  • 事件计数 : 使用 perf stat 统计特定事件的发生次数。
5. 高级用法
  • 调试符号: 确保程序带有调试符号以获得更详细的信息。
  • CPU Cache 分析: 分析缓存使用情况。
  • 硬件计数器: 分析底层事件如分支预测错误。
  • 系统调用跟踪 : 使用 perf trace 跟踪系统调用。
  • 脚本接口: 生成自定义报告。
6. 注意事项

调整 /proc/sys/kernel/perf_event_paranoid/proc/sys/kernel/kptr_restrict 设置,允许非特权用户使用性能分析功能。

7. 可能遇到的问题
问题1: perf_event_paranoid 设置限制

根据错误信息,可能需要降低 perf_event_paranoid 设置值,以允许当前用户使用 perf 工具。可以临时或永久调整此设置。

问题2: kptr_restrict 设置导致内核样本无法解析

由于 kptr_restrict 设置,内核符号被限制访问。可以临时或永久调整此设置,或者确保有匹配的 vmlinux 文件用于解析内核样本。

注意:调整这些设置可能会带来安全风险,应谨慎操作,并考虑生产环境中的安全性需求。

相关推荐
chenbin52025 分钟前
Jenkins 自动构建Job
运维·jenkins
java 凯27 分钟前
Jenkins插件管理切换国内源地址
运维·jenkins
AI服务老曹30 分钟前
运用先进的智能算法和优化模型,进行科学合理调度的智慧园区开源了
运维·人工智能·安全·开源·音视频
风静如云2 小时前
OpenBMC:BmcWeb定义service
linux
sszdzq2 小时前
Docker
运维·docker·容器
book01212 小时前
MySql数据库运维学习笔记
运维·数据库·mysql
leoufung2 小时前
VIM FZF 安裝和使用
linux·编辑器·vim
bugtraq20213 小时前
XiaoMi Mi5(gemini) 刷入Ubuntu Touch 16.04——安卓手机刷入Linux
linux·运维·ubuntu
xmweisi3 小时前
【华为】报文统计的技术NetStream
运维·服务器·网络·华为认证
VVVVWeiYee3 小时前
BGP配置华为——路径优选验证
运维·网络·华为·信息与通信