欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > Linux内核perf性能分析工具案例分析

Linux内核perf性能分析工具案例分析

2025/4/1 11:48:14 来源:https://blog.csdn.net/m0_74186706/article/details/146775103  浏览:    关键词:Linux内核perf性能分析工具案例分析

一、系统级性能分析工具perf原理        

1. perf 的基本概念

  • 内核集成:perf 直接集成在 Linux 内核源码中,能够深度访问硬件和操作系统层面的性能数据,具有低开销、高精度的特点。

  • 事件采样原理:通过定期采样系统事件(如 CPU 周期、指令执行、缓存访问等),统计热点代码和资源消耗,帮助定位性能瓶颈。


2. 系统级性能优化的两个阶段

(1) 性能剖析(Performance Profiling, PP)
  • 目标:识别系统的瓶颈,如 CPU 利用率过高、内存泄漏、I/O 延迟等。

  • 方法:通过 perf 收集硬件事件(如 CPU 周期)、软件事件(如上下文切换)和追踪点(TracePoint)数据,生成性能报告。

  • 输出:确定程序中耗时最多的函数(热点代码)、资源争用情况等。

(2) 代码优化
  • 目标:基于剖析结果,针对性优化代码或调整系统配置。

  • 常见手段

    • 优化算法复杂度;

    • 减少锁竞争或使用无锁数据结构;

    • 改善缓存局部性;

    • 调整内存分配策略等。


3. perf 的核心技术支撑

perf 依赖以下三类技术收集性能数据:

(1) PMU(Performance Monitoring Unit)
  • 硬件支持:PMU 是 CPU 内置的硬件单元,用于监控处理器级事件。

  • 监控事件

    • CPU 周期(cycles)、指令数(instructions);

    • 缓存命中/失效(cache-misses, cache-references);

    • 分支预测失败(branch-misses)等。

  • 优势:直接访问硬件计数器,精度高、开销极低。

(2) TracePoint
  • 内核静态探针:TracePoint 是 Linux 内核中预定义的静态跟踪点,用于记录特定事件的发生。

  • 监控事件

    • 系统调用(syscalls)、调度事件(sched_switch);

    • 文件 I/O(ext4 文件系统操作)、网络包处理等。

  • 优势:提供细粒度的内核行为追踪,适用于分析系统调用和内核态性能问题。

(3) 内核计数器
  • 软件统计:内核通过计数器记录系统事件的发生次数。

  • 监控事件

    • 上下文切换(context-switches)、缺页异常(page-faults);

    • 进程创建(process-fork)等。

  • 优势:适用于统计类性能分析,如系统负载分布。


4. perf 的典型使用场景

(1) CPU 瓶颈分析
  • 命令示例

    perf record -g -e cycles ./my_program  # 记录程序的 CPU 周期事件
    perf report                            # 生成热点函数报告
  • 输出:显示消耗最多 CPU 周期的函数及其调用栈。

(2) 缓存效率分析
  • 命令示例

    perf stat -e cache-references,cache-misses ./my_program
  • 输出:统计缓存命中率,帮助优化内存访问模式。

(3) 内核行为追踪
  • 命令示例

    perf trace -e syscalls:sys_enter_openat  # 追踪文件打开操作
  • 输出:记录所有 openat 系统调用的参数和频率。


5. perf 的优势与对比

  • 优势

    • 低开销:基于事件采样而非全量记录,对系统影响小;

    • 多功能性:支持硬件事件、内核事件、用户态程序分析;

    • 深度集成:直接利用内核基础设施,无需额外插桩。

  • 对比其他工具

    • gprof:仅支持用户态函数耗时统计,无内核级支持;

    • Valgrind:功能强大但开销极高,适合内存调试而非性能分析。

 

二、安装性能分析工具perf与perf list命令

1.安装性能分析工具perf

sudo apt-get update
sudo apt-get install linux-tools-generic linux-cloud-tools-generic

        我这里已经安装过了:

        执行perf命令如下,证明已经成功安装perf性能分析工具了。

         查看当前perf所支持的性能事件列表如下(有软件也有硬件的):

 除此之外还有常用的命令如下:

  • perf list:查看当前系统支持的性能事件
  • perf bench:针对系统性能进行摸底
  • perf test:针对系统进行健全性能测试
  • perf stat:对全局性能进行统计
  • perf top:针对实时查看当前系统进程函数占用率情况
  • perf probe:自定义动态事件

【perf list sw】

命令作用

perf list sw 用于列出系统中 软件模拟的性能事件。其中:

  • perf list 基础功能是展示系统预定义的性能事件;
  • sw 是过滤条件,用于筛选出类型为 [Software event](软件事件)的条目,这些事件由内核通过软件层面统计生成,而非硬件计数器直接采集。

输出含义

输出结果为符合条件的性能事件列表,格式为 事件名称 [事件类型],具体含义:

 
  • 事件名称
    • 如 alignment-faults(内存对齐错误次数)、context-switches OR cs(上下文切换次数,OR 表示别名)、cpu-clock(CPU 活动时间)等,是性能分析的具体观测对象,反映系统软件层面的行为(如进程调度、内存管理等)。
  • 事件类型
    • [Software event]:表示该事件由内核通过软件模拟统计(例如上下文切换、内存页错误等,无需硬件计数器支持);
    • 图中少量 [Tool event] 属于输出异常(正常 sw 过滤应仅含 Software event),可能是系统版本或工具特性导致,[Tool event] 与 perf 工具自身功能相关(如时间统计),一般不归类于常规软件事件。

 【perf list cache】

命令作用

perf list cache 用于列出系统中与 缓存(Cache)相关的预定义性能事件,这些事件可用于分析 CPU 缓存(如一级数据缓存、指令缓存、TLB 等)的访问、命中 / 缺失情况,帮助定位缓存相关的性能瓶颈。

输出含义

输出内容为缓存相关的性能事件列表,格式为 事件名称,具体解释:

  • 事件分类
    • 以 cpu: 开头,表明这些事件与 CPU 缓存相关,基于硬件计数器统计。
  • 常见事件示例
    1. L1-dcache-loads OR cpu/L1-dcache-loads/
      • 表示 CPU 一级数据缓存(L1 Data Cache)的加载次数,用于统计从 L1 数据缓存中读取数据的操作数量。
    2. L1-dcache-load-misses OR cpu/L1-dcache-load-misses/
      • 表示 CPU 一级数据缓存加载缺失次数,即读取数据时在 L1 数据缓存中未命中,需从更高层级缓存或内存获取的次数。
    3. L1-icache-loads OR cpu/L1-icache-loads/
      • 表示 CPU 一级指令缓存(L1 Instruction Cache)的加载次数,统计从 L1 指令缓存中读取指令的操作数量。
    4. dTLB-loads OR cpu/dTLB-loads/
      • 表示数据转换查找缓冲(Data Translation Lookaside Buffer, dTLB)的加载次数,用于统计数据地址转换时 TLB 的访问情况。
    5. branch-loads OR cpu/branch-loads/
      • 表示分支指令缓存的加载次数,统计分支指令相关的缓存访问操作。
 

这些事件可通过 perf stat -e 事件名 等命令结合具体工具(如 perf stat perf record),深入分析程序运行时的缓存使用效率。

 

三、使用perf采集数据信息/perf stat|top

1.perf stat全局性能统计如下:

命令作用

perf stat ls 用于运行 ls 命令(列出当前目录文件),同时收集并展示该命令执行过程中的性能计数器统计信息,帮助分析程序对 CPU、内存等资源的使用情况。

输出内容详解

1. 命令执行结果
FlameGraph grpc linux-5.6.18  linux-5.6.18.tar.gz  mosquitto-2.0.15  snap  tmp  work  workflow  zvfs  

这是 ls 命令的正常输出,显示当前目录下的文件和文件夹。

2. 性能计数器统计(Performance counter stats for 'ls'
  • 1.66 msec task-clock
    • 含义:任务(即 ls 命令)占用的 CPU 时间,单位为毫秒。
    • 关联计算:CPUs utilized = task-clock / time elapsed,用于计算 CPU 利用率(本例中通过后续 0.583 CPUs utilized 体现)。
  • 2 context-switches
    • 含义:ls 执行过程中发生的上下文切换次数,反映进程在运行中被调度器暂停 / 恢复的频率。
  • 0 cpu-migrations
    • 含义:CPU 迁移次数,即进程在不同 CPU 核心间迁移的次数(本例未发生迁移)。
  • 103 page-faults
    • 含义:缺页异常次数,即访问的内存页面不在物理内存中,需从磁盘加载的次数。
  • 3,073,664 cycles
    • 含义:CPU 消耗的周期数,反映指令执行的硬件耗时(结合 1.856 GHz 可辅助分析频率影响)。
  • 0 stalled-cycles-frontend
    • 含义:前端停滞周期数,指 CPU 指令获取或解码阶段的停滞情况(本例无停滞)。
  • 0 instructions
    • 含义:执行的指令数量。0.00 insn per cycle 表示每周期执行指令数为 0(可能因统计范围或事件未完全计数导致)。
  • 0 branches
    • 含义:分支指令数量,统计程序中条件跳转等分支操作的次数。
  • 0 branch-misses
    • 含义:分支预测错误次数,若分支指令预测错误,会导致流水线刷新,影响性能(本例未统计到,提示 <not counted>)。
3. 时间统计
  • 0.002841599 seconds time elapsed
    • 含义:从命令开始到结束的总耗时(墙钟时间)。
  • 0.001439000 seconds user
    • 含义:ls 在用户态执行的时间。
  • 0.001439000 seconds sys
    • 含义:ls 在内核态(系统调用)执行的时间。
4. 统计提示
Some events weren't counted. Try disabling the NMI watchdog...  
  • 含义:部分事件(如 branch-misses)未成功计数,提示通过关闭 NMI 看门狗(修改 /proc/sys/kernel/nmi_watchdog)尝试解决统计问题。

 2.perf top指定性能事件,消耗最多的函数或指令

perf top 命令作用

perf top 是 Linux 性能分析工具 perf 的子命令,主要用于实时分析系统中各函数在特定性能事件(如 CPU 周期、缓存命中 / 缺失等)上的 “热度”。它通过采样统计,快速定位消耗资源最多的函数(包括应用程序函数、内核函数、动态链接库函数等),帮助开发者或运维人员识别系统性能瓶颈,例如哪些内核函数占用过多 CPU 周期、哪些应用函数存在效率问题等。


结合输出的详细分析(以图中内容为例)

输出表格包含四列,每列含义及对应图中内容分析如下:

1. 第一列:符号引发的性能事件比例
  • 含义:表示该函数在性能事件(默认是 CPU 周期)中占用的比例,反映函数对性能事件的 “贡献度”,比例越高,说明该函数越消耗资源。
  • 图中示例
    • 24.22%:表示 mpt_put_msg_frame 函数占用了约 24.22% 的 CPU 周期,是当前采样中最 “热” 的函数。
    • 20.46%pv_native_safe_halt 函数占用 20.46% 的 CPU 周期,也是主要的资源消耗点。
2. 第二列:符号所在的 BSO(Binary/Symbol Object)
  • 含义:标识函数所属的二进制对象,可能是内核、动态链接库、应用程序或内核模块等。
  • 图中示例
    • [kernel]:表示函数属于内核(如 mpt_put_msg_frame pv_native_safe_halt 等)。
    • perf:表示函数属于 perf 工具本身(如 io_get_char rb_next 等)。
    • libc.so.6:表示函数属于 C 标准库(如 _int_malloc _libc_calloc 等)。
3. 第三列:BSO 的类型
  • 含义
    • [k]:表示符号属于内核空间(内核代码或内核模块)。
    • [.]:表示符号属于用户空间的 ELF 文件(如应用程序、动态链接库)。
  • 图中示例
    • [k]:如 mpt_put_msg_frame pv_native_safe_halt 等内核函数。
    • [.]:如 io_get_char(属于 perf 工具的用户态函数)。
4. 第四列:符号名称或地址
  • 含义
    • 若能解析为函数名,直接显示函数名(如 mpt_put_msg_frame _int_malloc);
    • 若无法解析(如匿名函数、代码地址),则显示地址(如 0x00000000000b91e7)。
  • 图中示例
    • mpt_put_msg_frame:内核中可解析的函数名。
    • 0x00000000000b91e7:无法解析为函数名,仅显示地址的符号。

总结

        通过 perf top 的输出,可快速定位系统中资源消耗最大的函数。例如图中内核函数 mpt_put_msg_frame 和 pv_native_safe_halt 占据较高比例,若系统存在 CPU 利用率过高的问题,就可优先分析这些函数的逻辑是否存在优化空间。

 

 3.perf record

        perf record 精确到函数级别(混合显示汇编语言和代码),就是我们运行此工具命令之后,将其数据保存到 perf.data 中,我们也可以通过 perf report 进行分析。   

perf record 工具命令常用选项:
        -e-->record 指定 PMU 事件(--filter event 事件过滤器)
        -a--> 获取所有 CPU 事件
        -p--> 获取指定 PID 进程的事件
        -o--> 指定获取保存数据的文件名称
        -g--> 能够使函数调用图功能
        -C--> 获取指定 CPU 事件

【具体案例】

testfork.c

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>int main() {int i;for (i = 0; i < 5; i++) {pid_t pid = fork();if (pid == 0) {  // 子进程int j;for (j = 0; j < 100000; j++) {int x = j * j;  // 模拟计算}return 0;} else if (pid > 0) {  // 父进程wait(NULL);  // 等待子进程结束} else {perror("fork");return 1;}}return 0;
}

编译采集:

 接着执行命令 perf report --call-graph none

 

四、采集perf数据信息生成火焰图

  • 火焰图(flame graph)是性能分析的利器,通过它可以快速定位性能瓶颈点。
  • perf 命令(performance 的缩写)是 Linux 系统原生提供的性能分析工具,会返回 CPU 正在执行的函数名以及调用栈(stack)。

使用步骤

1.下载FlameGraph包

curl -O http://example.com/FlameGraph.zip  

2.生成perf.unfold文件

        perf script -i perf.data &> perf.unfold

        如果中间出现权限问题Permission denied ,可以使用chmod u+x 增加执行权限。

3.生成perf.folded文件

        ./FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded 

下面这两行命令和上面两行命令功能相同,也可以生成需要的perf.folded

perf script > perf.script

./FlameGraph/stackcollapse-perf.pl perf.script > perf.folded   

4.生成perf.svg文件

         ./FlameGraph/flamegraph.pl perf.folded > perf.svg 

5.打开火焰图

 

https://github.com/0voice

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词