perf record/report用法详解

性能优化
性能优化通常分为两个阶段:性能分析、性能优化


perf 概述
perf 是 Linux 下的一款性能分析工具,可以用来分析程序中热点函数的 CPU 占用率,从而定位性能瓶颈。
perf 核心功能由 Performance counters(性能计数器) 子系统实现,它提供一个性能分析框架,比如硬件(CPU、PMU(Performance Monitoring Unit))功能和软件(软件计数器、tracepoint)功能。
通过 perf,应用程序可以利用 PMU、tracepoint 和内核中的计数器来进行性能统计。

perf 可以对程序进行函数级和指令级的采样,从而了解程序的性能瓶颈在哪里。
基本原理:在采样时间内,每隔一个固定采样周期,在 CPU 上产生一个中断,看当前是哪个进程、哪个函数在运行,然后就给对应的进程和函数加一个统计值,这样就可以估算出这段采样时间内,CPU 有多少时间花在某个进程和某个函数上。
perf 工具功能非常多,今天我们就来学习最常使用的两个命令:perf record 和 perf report。其中,一个用来统计,一个用来展示。

示例
使用下面这个示例程序,来学习 perf record/report 命令的使用。
perftest.c

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

void for_loop()
{
    int i, j;
    int x;

    for (i = 0; i < 1000; i++) {
        for (j = 0; j < 10000; j++) {
            x = sin(i) + cos(j);
        }
    }
}

void loop_samll()
{
    int i;

    for (i = 0; i < 10; i++) {
        for_loop();
    }
}

void loop_big()
{
    int i;

    for (i = 0; i < 100; i++) {
        for_loop();
    }
}

int main(int argc, char *argv[])
{

    printf("pid = %d\n", getpid());
    loop_big();
    loop_samll();

    return EXIT_SUCCESS;
}


$ gcc -o perftest.out perftest.c -lm
$ ./perftest.out 
pid = 826526

perf record
$ sudo perf record -p 826526 -a -g -F 99 -- sleep 10

-p:分析指定进程
-a:对所有 CPU 进行采样
-g:启用调用追溯功能
-F:指定采样频率
-- sleep:采集时长
执行这个命令后,会在当前目录下产生一个 perf.data 文件,接下来就可以使用 perf report 命令来分析这份采样记录了。

这个命令使用 perf 工具在 Linux 上记录程序的性能数据。perf 是一个强大的性能分析工具,用于测量和评估 Linux 内核和应用程序的性能。

  1. sudo: 这个命令用于以超级用户(root)权限运行 perf record。因为性能分析可能涉及到系统级别的信息,所以需要更高的权限来执行。

  2. perf record: 这是 perf 工具的一个子命令,用于记录性能数据。这些数据可以包括 CPU 指令的执行、内存访问、缓存未命中、分支预测错误等。

  3. -p 826526: 这个参数指定了 perf record 要监控的进程 ID(PID)。在这个例子中,它正在监控 PID 为 826526 的进程。

  4. -a: 这个参数告诉 perf 记录所有 CPU 上的数据,而不仅仅是单个 CPU。

  5. -g: 这个参数启用了函数级别的调用图记录。这意味着 perf 会记录每个函数调用的堆栈信息,这对于分析函数调用关系非常有用。

  6. -F 99: 这个参数设置了数据采样的频率。在这个例子中,它告诉 perf 每 99 个 CPU 事件就记录一次样本。这个值可以根据需要调整,以获取更精细或更粗糙的性能数据。

  7. --: 这个符号用于分隔 perf record 的参数和接下来要运行的命令。

  8. sleep 10: 这是 perf record 命令之后要运行的命令。在这个例子中,sleep 10 命令会让进程休眠 10 秒钟。这通常用于生成一些性能数据,因为 perf record 会记录在这个命令执行期间发生的所有事件。

综上所述,监控 PID 为 826526 的进程,在所有 CPU 上以 99 个事件一次的频率记录性能数据,并生成一个包含函数调用图的报告。同时,它会运行 sleep 10 命令来生成一些性能数据。在 10 秒后,perf record 会停止记录并保存性能数据,以供后续分析。

perf report
$ sudo perf report

通过 perf report 命令可以展示采样记录,大概介绍下面板参数

Samples:采样个数
Event count:系统总共发生的事件数
Symbol:函数名,其中 [.] 表示用户空间函数,[k] 表示内核函数
Shared Objec:函数所在的共享库或所在的程序
Command:进程名
Self:该函数的 CPU 使用率
Children:该函数的子函数的 CPU 使用率
那么,通过示例的展示面板,我们能得到的信息如下:

这次采样,是对 perftest.out 这个进程进行采样
总共采集到了 991 个事件(符合 -F 99 -- sleep 10,即,一秒钟采样 99 次,采样 10 秒钟)
第一行:__libc_start_main 函数,处于用户空间,处于共享库 libc-2.31.so 中,CPU 使用率为 0,其子函数的 CPU 使用率为 47.63%。(因为 __libc_start_main 只调用一次,实际使用 CPU 的都是其子函数)
第二行:main 函数同 __libc_start_main
第三行:loop_big 函数同 __libc_start_main
第四行:__sin_avx 函数,自身 CPU 使用率为 40.36%,子函数 CPU 使用率为 40.36%,说明其没有子函数。
第五行:__cos_avx 函数,CPU 使用率为 38.65%
第六行:for_loop 函数,CPU 使用率 20.99%
通过以上分析,可以知道 CPU 大部分时间都花在执行 sin() 和 cos() 这两个函数上,和示例代码吻合。

                  
原文链接:https://blog.csdn.net/lyndon_li/article/details/127472703

  • 46
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值