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 文件用于解析内核样本。

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

相关推荐
laimaxgg几秒前
Linux关于华为云开放端口号后连接失败问题解决
linux·运维·服务器·网络·tcp/ip·华为云
浪小满3 分钟前
linux下使用脚本实现对进程的内存占用自动化监测
linux·运维·自动化·内存占用情况监测
东软吴彦祖16 分钟前
包安装利用 LNMP 实现 phpMyAdmin 的负载均衡并利用Redis实现会话保持nginx
linux·redis·mysql·nginx·缓存·负载均衡
艾杰Hydra41 分钟前
LInux配置PXE 服务器
linux·运维·服务器
多恩Stone1 小时前
【ubuntu 连接显示器无法显示】可以通过 ssh 连接 ubuntu 服务器正常使用,但服务器连接显示器没有输出
服务器·ubuntu·计算机外设
慵懒的猫mi1 小时前
deepin分享-Linux & Windows 双系统时间不一致解决方案
linux·运维·windows·mysql·deepin
Allen Bright1 小时前
使用 JMeter 的 Autostop Listener 插件:自动化性能测试的守护者
运维·jmeter·自动化
晚秋贰拾伍1 小时前
设计模式的艺术-代理模式
运维·安全·设计模式·系统安全·代理模式·运维开发·开闭原则
阿无@_@1 小时前
2、ceph的安装——方式二ceph-deploy
linux·ceph·centos
hhzz1 小时前
ansible自动化运维实战--复制模块和用户模块(3)
运维·自动化·ansible