当前位置: 代码网 > 服务器>服务器>Linux > Linux下性能分析工具Perf安装与用法

Linux下性能分析工具Perf安装与用法

2024年06月17日 Linux 我要评论
1、perf介绍perf是linux下的一款性能分析工具,能够进行函数级与指令级的热点查找。它由一个叫“performance counters“的内核子系统实现,基于事件采样

1、perf介绍

perf是linux下的一款性能分析工具,能够进行函数级与指令级的热点查找。它由一个叫“performance counters“的内核子系统实现,基于事件采样原理,以性能事件为基础,支持针对处理器相关性能指标与操作系统相关性能指标的性能剖析,可用于性能瓶颈的查找与热点代码的定位。

perf的主要功能和用途如下:

事件采样:perf使用硬件性能计数器来采样事件,如cpu指令、缓存命中、缓存失效等,从而获取系统在运行时的性能数据。

调用图:perf可以生成函数调用图,显示函数之间的调用关系和耗时,帮助识别程序的热点和性能瓶颈。

火焰图:火焰图是perf输出的一种可视化图表,它可以直观地展示函数调用的耗时情况和函数的调用关系,以便快速准确地识别最频繁的代码路径,帮助快速定位性能瓶颈。

内存分析:perf可以收集内存事件,如内存访问、缺页异常等,帮助识别内存性能问题。

锁分析:perf可以监测锁的使用情况,帮助发现多线程程序中的竞争问题。

tracing支持:perf支持linux trace toolkit next generation (lttng)和ebpf等跟踪工具,用于深入分析系统的行为。

报告生成:perf能够生成详细的报告和统计信息,方便用户理解和分析性能数据。

2、火焰图分类

(1)cpu

用途:检测导致cpu运行繁忙的原因。

(2)memory flame graphs

用途:检测应用程序内存使用量增加的原因。

(3)off-cpu flame graphs

用途:有些性能问题不是cpu的性能问题,即进程和线程不在cpu上运行时花费角度的时间,而是在程序请求期间花费了不少时间,这种情况也会成比例的影响性能。

(4)hot/cold flame graphs

用途:将cpu和非cpu火焰图结合在一起。它在一个图表中显示了所有线程的运行时间,并允许直接比较在cpu和非cpu上的代码路径持续时间。

(5)differential

用途:红蓝差异火焰图,分析不同时刻cpu性能变化的原因。

 3、火焰图安装命令

(1)安装perf工具

$ sudo apt-get install linux-tools-$(uname -r) linux-tools-generic -y    //下载perf
$ perf -v    //查看安装perf的版本

(2)下载可视化工具flamegraph

下载地址:github - brendangregg/flamegraph: stack trace visualizer

 4、火焰图demo测试

测试程序如下:

#include <stdio.h>
#define def_print    
 
 
void funca()
{
    for(int i=0; i < 10*10000;i++)
    {
#ifdef def_print
       printf("funca\n");
#endif
    }
}
 
void funcb()
{
    for(int i=0; i < 20*10000;i++)
    {
#ifdef def_print
         printf("funcb\n");
#endif
    }
}
 
void funcc()
{
    for(int i=0; i < 30*10000;i++)
    {
#ifdef def_print
         printf("funcc\n");
#endif
    }
}
 
void printf1();
void printf2();
void funcd()
{
    for(int i=0; i < 20*10000;i++)
    {
#ifdef def_print
         printf("funcd\n");
#endif
    }
    printf1();
}
 
void printf1()
{
    for(int i=0; i < 10*10000;i++)
    {
#ifdef def_print
         printf("printf1\n");
#endif
    }
    printf2();
}
 
void printf2()
{
    for(int i=0; i < 10*10000;i++)
    {
#ifdef def_print
        printf("printf2\n");
#endif
    }
}
 
int main()
{
    while (true) {
        funca();
        funcb();
        funcc();
        funcd();
    }
    return 0;
}

程序编译命令:

g++ -g -o0 main.cpp -o main //-g带调试信息编译,禁止优化o0,

(1)生成cpu火焰图1

生成火焰图步骤如下:

程序运行结果如下:

//上面main程序运行时,使用top查看,进程pid为5606,cpu为86.3%左右。
 
$ sudo perf record -f 99 -p 5606 -g -- sleep 30
//-f 99 表示每秒99次采样, -p 5606 是进程号, 即对哪个进程进行分析, -g 表示记录调用栈, sleep 30 则是持续30秒。
 
$ sudo perf script -i perf.data &>perf.unfold
//perf script 工具对 perf.data 进行解析,生成折叠后的调用栈。
 
$ ../flamegraph/stackcollapse-perf.pl perf.unfold &>perf.folded
//下载的可视化工具flamegraph在当前文件上一层,用 stackcollapse-perf.pl 将 perf 解析出的内容 perf.unfold 中的符号进行折叠。
 
$ ../flamegraph/flamegraph.pl perf.folded >perf1.svg
//生成svg图

使用浏览器打开perf.svg图,效果如下:

(2)火焰图表解析

上图中每个方块代表堆栈中的一个函数,也叫堆栈帧。

y轴:表示堆栈深度,火焰越高,表示函数调用层级越深,最顶部的方块表示当前cpu上运行的函数,每一块的函数下方都是当前函数的调用方。

x轴:表示当前函数的采样数,与大多数图表不同,它不显示从左到右的时间流逝。左到右的排序没有意义(它按字母顺序排序以最大程度地合并帧),方框的宽度显示了它在cpu上运行的总时间(基于采样计数)。哪个方块的宽度比较大,就表示该函数可能存在性能问题。

注意:图标中颜色不具有显著意义,通常是随机选择的暖色调。这种可视化称为"火焰图",因为它最初用于显示cpu上的热点,而且看起来像火焰。

它也是交互式的:将鼠标悬停在svg上以显示详细信息,并单击进行缩放。

(3)当前程序图标分析

从(1)中火焰图中看出,没有demo中定义的函数,这是因为printf函数占用改进程的cpu性能较高,而for循环逻辑占用性能较低,可以点击火焰图上的搜索按键search进行搜索,本文搜索程序入口函数。

确定入口函数的步骤如下:

a> 入口函数地址确定

输入下面命令

$ readelf -h main

可执行文件信息如下: 

b> 获取对应地址入口函数

输入下面命令:

$ readelf -s main

由上图可知入口函数为_start,所以搜索_start函数。

_start搜索结果如下:

点击__libc_start_main函数,进入对于函数调用过程,如下:

(4)生成火焰图2

将上面的代码中的#define def_print  行进行屏蔽,这样函数就不会打印输出到屏幕上。重新编译代码,运行。

生成火焰图步骤跟上面(1)中一样,只是-p参数的进程id号不同,生成的svg图片如下:

由svg图表可知,funca在mainnoprint进程中,占用该进程cpu 10%,funcb占用该进程cpu 20%,funcc占用该进程cpu 30%,funcd占用该进程cpu 40%。 

(5)生成差分火焰图

运行mainnoprint函数,抓取系统所有进程的cpu,命令如下:

$ sudo perf record -f 99 -a -g -- sleep 30     //a表示对所有进程堆栈数据进行抓取
$ sudo perf script -i perf.data &>perf.unfold
$ ../flamegraph/stackcollapse-perf.pl perf.unfold &>perf.folded1
$ ../flamegraph/flamegraph.pl perf.folded1 >perf1.svg

生成的火焰图如下:

停止mainnoprint程序,抓取系统所有进程的cpu,命令如下:

$ sudo perf record -f 99 -a -g -- sleep 30
$ sudo perf script -i perf.data &>perf.unfold
$ ../flamegraph/stackcollapse-perf.pl perf.unfold &>perf.folded2
$ ../flamegraph/flamegraph.pl perf.folded2 >perf2.svg

生成的火焰图如下:

以perf.folded2的为基准,生成差分火焰图,命令如下:

$./flamegraph/difffolded.pl perf.folded2 perf.folded1|../flamegraph/flamegraph.pl >diff1.svg

生成的差分火焰图如下:

由红色部分图可知,cpu中funcd等函数占用的cpu增加了,蓝色部分相对于上次cpu减少了。

以上就是linux下性能分析工具perf安装与用法的详细内容,更多关于linux perf安装与使用的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com