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

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

相关推荐
残雪飞扬12 分钟前
Ubuntu上安装 WinBoat(让linux上运行windows软件)
linux·windows·ubuntu
m0_6831247913 分钟前
无U盘装Ubuntu
linux·运维·ubuntu
默|笙15 分钟前
【Linux】进程信号(2)_信号捕捉_中断
linux·运维·服务器
东方不败之鸭梨的测试笔记17 分钟前
UI自动化执行时,元素不在视野内,需要拖动滑动条才能找到,这种元素怎么处理?
运维·ui·自动化
图灵机z20 分钟前
【操作系统】四、进程管理
linux·服务器·网络·windows·macos·centos·risc-v
新新学长搞科研27 分钟前
【高届数人工智能会议】第七届人工智能、网络与信息技术国际学术会议(AINIT 2026)
运维·网络·人工智能·计算机网络·自动化·信号处理·可信计算技术
KKKlucifer29 分钟前
特权账号管理与运维安全审计核心技术
运维·安全
haaaaaaarry34 分钟前
【操作系统】第三章 内存管理(一)
linux·考研·操作系统
牛奶咖啡1334 分钟前
DevOps自动化运维实践_基于Cobbler搭建UEFI网络引导的自动安装平台
linux·运维·自动化·uefi·pxe·uefi网络引导自动安装平台·tftp dhcp 环境搭建
云飞云共享云桌面36 分钟前
东莞智能装备工厂10个solidworks共享一台服务器做装配体设计
运维·服务器·网络·云计算·电脑