perf性能分析工具

一、介绍

perf用法perf Examples
程序示例
火焰图Linux C/C++性能优化分析工具Perf使用教程-哔哩哔哩

perf是一个性能分析工具。可以知道哪些函数调用次数多导致性能消耗大。

二、安装

2.1 安装

perf工具跟内核版本强相关,需要安装linux-tools-common。安装步骤:

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

2.2 运行可执行文件

可以直接使用安装的路径运行

# /usr/lib/linux-tools/5.15.0-152-generic/perf --version
perf version 5.15.185

也可以设置软链接。不同内核版本目录5.15.0-152-generic会有所区别。

ln -s /usr/lib/linux-tools/5.15.0-152-generic/perf /usr/bin/perf  

注:如果/usr/bin/下本来就有perf文件则会报错,说明已经安装过。

// 报错提示
# perf --version
WARNING: perf not found for kernel 5.15.0-60

  You may need to install the following packages for this specific kernel:
    linux-tools-5.15.0-60-generic
    linux-cloud-tools-5.15.0-60-generic

  You may also want to install one of the following packages to keep up to date:
    linux-tools-generic
    linux-cloud-tools-generic

三、使用方法

初学时可以找个简单的程序理解perf的用法。我用附录中的演示程序为例讲解perf的使用方法。

3.1 查询需要监控的进程ID

perf是监控进程号的,所以先用ps命令查询得到进程ID。

# ps -ef | grep process_print
root       14712    7403 99 14:54 ?        01:52:17 ./process_print

3.2 perf监控进程

perf record -p 14712 -g 

收集一段时间可以Ctrl+C退出监控。

3.3 perf生成报告

perf report -g

# ls
perf.data

3.3.1 将perf数据生成生成文本

方法2:转成文本可以直接看函数的占比。

// 生成perf数据txt 
perf report -i perf.data > perf.txt

# ls
perf.data  perf.txt

3.3.2 将perf数据生成生成火焰图

  1. 火焰图环境安装
    生成火焰图只需要一些脚本将数据绘图。这些脚本下载
git clone https://github.com/brendangregg/FlameGraph.git 

# ls
FlameGraph  perf.data
  1. 将perf数据绘制成火焰图
perf script -i perf.data > perf.unfold
FlameGraph/stackcollapse-perf.pl perf.unfold > perf.folded
FlameGraph/flamegraph.pl perf.folded > perf.svg

# ls
FlameGraph  perf.data  perf.folded  perf.svg  perf.unfold

四、分析数据

最终我们得到perf的火焰图后我们可以对数据进行分析。火焰图中函数宽度就是耗时,高度表示调用层级越多。

perf.svg
perf

perf原理

https://developer.aliyun.com/article/65255
【Linux Perf 底层数据收集机制概述(码题诗科技)-哔哩哔哩】

perf工具指定跟踪的进程,看系统调用次数。

附录

1 演示程序

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

void func1( void )
{
    printf("process (PID:%d) printing...\n", getpid());
    return;
}

int main() {
    pid_t pid = fork();

    if (pid < 0) {
        perror("fork failed");
        return 1;
    } else {
        while(1) {
            func1();
            sleep(2);
        }
    }
    return 0;
}

编译

gcc process_print.c -o process_print  
./process_print

2 perf.txt数据

# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 2  of event 'cpu-clock:pppH'
# Event count (approx.): 500000
#
# Children      Self  Command        Shared Object      Symbol                            
# ........  ........  .............  .................  ..................................
#
   100.00%   100.00%  process_print  [kernel.kallsyms]  [k] syscall_enter_from_user_mode
            |          
            |--50.00%--0x7fe87c38bd90
            |          main
            |          __getpid
            |          entry_SYSCALL_64_after_hwframe
            |          do_syscall_64
            |          syscall_enter_from_user_mode
            |          
             --50.00%--0x3339313a44495028
                       write
                       entry_SYSCALL_64_after_hwframe
                       do_syscall_64
                       syscall_enter_from_user_mode

   100.00%     0.00%  process_print  [kernel.kallsyms]  [k] entry_SYSCALL_64_after_hwframe
            |
            ---entry_SYSCALL_64_after_hwframe
               do_syscall_64
               syscall_enter_from_user_mode

   100.00%     0.00%  process_print  [kernel.kallsyms]  [k] do_syscall_64
            |
            ---do_syscall_64
               syscall_enter_from_user_mode

    50.00%     0.00%  process_print  libc.so.6          [.] 0x00007fe87c38bd90
            |
            ---0x7fe87c38bd90
               main
               __getpid
               entry_SYSCALL_64_after_hwframe
               do_syscall_64
               syscall_enter_from_user_mode

    50.00%     0.00%  process_print  process_print      [.] main
            |
            ---main
               __getpid
               entry_SYSCALL_64_after_hwframe
               do_syscall_64
               syscall_enter_from_user_mode

    50.00%     0.00%  process_print  [unknown]          [k] 0x3339313a44495028
            |
            ---0x3339313a44495028
               write
               entry_SYSCALL_64_after_hwframe
               do_syscall_64
               syscall_enter_from_user_mode

    50.00%     0.00%  process_print  libc.so.6          [.] __getpid
            |
            ---__getpid
               entry_SYSCALL_64_after_hwframe
               do_syscall_64
               syscall_enter_from_user_mode

    50.00%     0.00%  process_print  libc.so.6          [.] write
            |
            ---write
               entry_SYSCALL_64_after_hwframe
               do_syscall_64
               syscall_enter_from_user_mode



#
# (Cannot load tips.txt file, please install perf!)
#

posted @ 2025-08-23 10:44  liqinglucky  阅读(236)  评论(0)    收藏  举报