【linux性能分析】perf分析CPU占用详情

news2024/11/16 22:35:16

文章目录

        • 1. 如何使用perf工具
          • 1.1 perf安装
          • 1.2 首次使用perf报错
          • 1.3 添加测试程序
          • 1.4 编译并执行指令生成perf.data文件
          • 1.5 添加-g选项能查看call graph调用信息
          • 1.6 查看perf.data
          • 1.7 perf工作流
          • 1.8 sudo perf record -F 99 -p 2512 -g -- sleep 60
        • 2. 如何生成火焰图
          • 2.1 安装火焰图生成工具
          • 2.2 生成和创建火焰图的步骤
          • 2.3 火焰图的含义
          • 2.4 生成"红/蓝差分火焰图"示例
        • 3. 使用perf分析节点CPU占比

1. 如何使用perf工具
1.1 perf安装
  • 参考perf工具安装和使用

  • perf安装命令:

    sudo apt-get install linux-tools-$(uname -r) linux-tools-generic -y
    sudo apt-get install linux-tools-$(uname -r) linux-tools-generic -y --fix-missing
    
    perf -v		# 查看perf版本
    
1.2 首次使用perf报错
  • No permission to enable cycles: u event

  • 解决方法:直接修改 /proc/sys/kernel/perf_event_paranoid,按照报错提示修改为 -1

  • 如果是docker容器环境提示 read only file system, 新建容器的时候应该添加 privileged=true 赋予权限

1.3 添加测试程序
  • 新建并添加测试程序如下,输入代码
    touch main.cpp
    vim main.cpp
    
    #include <iostream>
    using namespace std;
    
    void delay()
    {
    	int i,j;
    	for(i = 0; i < 1000000; i++)
    		j=i;
    }
    
    void function_1()
    {
    	int i;
    	for(i=0 ; i < 10; i++)
    		delay();
    }
    
    void function_2()
    {
    	int i;
    	for(i = 0; i< 30; i++)
    		delay();
    }
    
    int main(void)
    {
    	std::cout << "begin: " << std::endl;
    	function_1();
    	function_2();
    	std::cout << "end!" << std::endl;
    }
    
1.4 编译并执行指令生成perf.data文件
  • 编译测试程序

    g++ main.cpp -o main
    
  • 生成perf.data

    sudo perf record ./main
    
1.5 添加-g选项能查看call graph调用信息
  • 添加-g选项查看调用信息

    sudo perf record -g ./main
    
1.6 查看perf.data
  • 生成热点函数占用CPU的比例

    perf report
    
  • 可以看到, 程序中main函数总体CPU资源占比(CPU时间片)97.85%, 其中delay函数占比97.59%, function_1和function_2的占比占比近7:3

1.7 perf工作流
1.8 sudo perf record -F 99 -p 2512 -g – sleep 60
  • record: 表示采集系统事件,没有采用-e执行采集事件,则默认采用CPU时钟周期
  • -F: 指定采样频率, 可以设置99, 1000等等, -F 99表示每秒采样99次, 如果99次都是同一函数, 说明CPU在这1s内都在执行这一函数, 可能存在性能问题. 频率越高,perf record获得的样本数量也会越多,分析结果会更加精细,但采样会使程序的运行变慢,因此需要根据具体情况选择合适的采样频率; 默认频率4000Hz
    在这里插入图片描述
  • -p: 指定进程号, 对某一进程进行分析
  • -g: 表示记录调用栈, 拿到程序的call graph信息
  • --sleep 60: 表示对进程持续分析60s
2. 如何生成火焰图
2.1 安装火焰图生成工具
  • Flame Graph工程实现了一套生成火焰图的脚本, 直接clone下来使用

    git clone https://github.com/brendangregg/FlameGraph.git
    
  • 该文件夹下有很多perf语言脚本, 可完成不同堆栈分析

2.2 生成和创建火焰图的步骤
  • 捕获堆栈: perf script -i perf.data &> perf.unfold

  • 折叠堆栈: ./FlameGraph/FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded

  • 生成火焰图: ./FlameGraph/FlameGraph/flamegraph.pl perf.folded > perf.svg

  • 各个步骤的含义:

    • 捕获堆栈: 可以使用 perf、systemtap、dtrace 等工具抓取程序的运行堆栈
    • 折叠堆栈: 对捕获的堆栈信息进行分析组合, 将重复的堆栈累计在一起, 从而体现出负载和关键路径, 由FlameGraph的stackcollapse程序生成, 注意程序路径
    • 生成火焰图: 分析由stackcollapse输出的堆栈信息的火焰图, 执行完后生成.svg图片
2.3 火焰图的含义
  • y轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数

  • x轴表示抽样数,如果一个函数在x轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间占比越大。注意,x轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的

  • 颜色无特殊含义, 因为火焰图表示CPU的繁忙程度, 所以一般选择暖色调

  • 火焰图就是看顶层的哪个函数占据的宽度最大。只要有"平顶",就表示该函数可能存在性能问题

  • 鼠标悬浮: (浏览器打开.svg图片)可显示函数名, 抽样抽中的次数, 占总抽样次数的百分比

  • 点击放大: 点击某一层,该层会占据所有宽度,显示详细信息,再点击左上角ResetZoom可恢复

  • 查找: Ctrl + F, 高亮显示查找的函数

  • 火焰图的缺陷: 调用栈可能不完整, 当调用栈过深时,某些系统只返回前面的一部分(比如前10层); 函数名可能缺失, 有些函数没有名字,编译器只用内存地址来表示(比如匿名函数), 有可能是编译器优化等级过高

  • FlameGraph我们习惯称之为"CPU火焰图", 还有"浏览器火焰图"(x轴是任务时间轴), “红/蓝差分火焰图”, 红蓝差分火焰图可以用来对比分析两次修改的性能差异, 红色表示上升, 蓝色表示下降, 由此来寻找根因; 此外还有"Memory Flame Graphs"(检测内存占用量增加的原因), “Off-CPU Flame Graphs”(不在CPU上运行的时间,如I/O时间等), “Hot/Cold Flame Graphs”(CPU和非CPU结合,显示所有线程的运行时间)

2.4 生成"红/蓝差分火焰图"示例
  • 修改源程序

    #include <iostream>
    using namespace std;
    
    void delay()
    {
    	int i,j;
    	for(i = 0; i < 1000000; i++)
    		j=i;
    }
    
    void function_1()
    {
    	int i;
    	for(i=0 ; i < 20; i++)
    		delay();
    }
    
    void function_2()
    {
    	int i;
    	for(i = 0; i< 20; i++)
    		delay();
    }
    
    int main(void)
    {
    	std::cout << "begin: " << std::endl;
    	function_1();
    	function_2();
    	std::cout << "end!" << std::endl;
    }
    
  • 重新编译执行

    g++ main.cpp -o main
    sudo perf record -g ./main		# 生成新的perf.data
    
  • 折叠堆栈

    perf script -i perf.data &> perf.unfold		# 生成新的perf.unfold
    ./FlameGraph/FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded1
    
  • 生成火焰图

    ./FlameGraph/FlameGraph/flamegraph.pl perf.folded1 > perf2.svg
    
  • 以perf.folded为基准,生成差分火焰图

    ./FlameGraph/FlameGraph/difffolded.pl perf.folded perf.folded1 | ./FlameGraph/FlameGraph/flamegraph.pl > diff.svg
    
  • 浏览器打开diff.svg

    红色部分表示function_1中delay耗时增加了, 蓝色部分表示function_2中delay耗时减少了, 和我们修改的预期是一样的

3. 使用perf分析节点CPU占比
  • 执行报错1:sudo perf record -g ./可执行文件, 执行失败。节点编译完成后报错找不到
    error while loading shared libraries: liblibstatistics_collector.so

  • 解决方法:搜索发现liblibstatistics_collector.so存在, 但通过export添加路径后不生效

    • export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/so_path 执行后不管用
    • sudo ldconfig # 动态链接库管理, 让不同目录下的动态链接库为系统所共享
    • 或者试下 ldconfig 然后 perf record -g ./可执行文件, 不要加sudo
    • 执行后生效
  • 执行报错2:上一步生成的perf.data执行perf report提示文件size field is 0
    data size field is 0 which is unexpected

  • 原因分析:看下来是perf record -g ./可执行文件的形式没有正确生成perf.data, 单独执行perf record进行采样

    top		# 查看程序PID = 228
    
    perf record -p 228 -g		# 生成perf.data, Ctrl + C结束录制
    
    perf report				# 可正常读取
    
  • 生成火焰图

    perf script -i perf.data &> perf.unfold		# 捕获堆栈
    
    ./FlameGraph/FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded	# 折叠堆栈
    
    ./FlameGraph/FlameGraph/flamegraph.pl perf.folded > perf.svg		# 生成火焰图
    
  • 浏览器打开.svg图片

    ros2的CPU占用,播包5min
    ros1的CPU占用,播包5min
  • 对比结论:

    • 节点总体CPU占用在102%
    • 长时播包测试可知,节点的CPU占用主要来自std::thread::State_impl占74.51%,其中主程序25%+多线程相关45%
    • 多线程相关的45%分析
      • 对比ros1的CPU占用,在ros2中节点的CPU占用高只是运行机制的差异
      • 对多线程管理占用的45%的CPU,包含除主程序外的多个任务:不同topic消息队列同步访问,消息转proto,消息收发同步;线程同步统计节点掉线信息;线程同步维护节点状态信息等
      • 此外,在添加多线程同步前,这部分的CPU还是1-2核占满,线程间阻塞同步的方式降低了一个核以上的CPU占用,但线程同步还存在一部分的CPU占用

 


 
创作不易,如有帮助,请点赞收藏支持
 


[参考文章]
[1].FlameGraph火焰图安装和用法
[2].perf工具简单demo
[3].火焰图分析程序性能
[4].perf工具和+火焰图种类+红蓝差分火焰图的生成等
[5].perf工具基础介绍
[6].perf的基本使用方法
[7].perf使用命令详情, 需要仔细看下
[8].perf和gperftools使用
[9].执行程序时找不到共享库
[10].perf介绍-较全

created by shuaixio, 2024.04.12

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1684416.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

技术前沿 |【自回归视觉模型ImageGPT】

自回归视觉模型ImageGPT 引言一、ImageGPT的基本原理与创新之处二、ImageGPT在图像生成、理解等视觉任务上的应用三、ImageGPT对后续视觉Transformer模型发展的影响四、ImageGPT的深入应用 引言 在人工智能的飞速发展中&#xff0c;视觉模型作为其中一个重要的分支&#xff0c…

Qt运行时,如何设置第一个聚焦的控件

问题&#xff1a;Qt第一个聚焦的控件&#xff0c;如何自行设置&#xff1f; 尝试&#xff1a; 1.在代码中设置 lineEdit->setFocus() 。无效&#xff01; 2.Qt Designer–打开form1.ui–菜单栏下一行–Edit Tab Order–按顺序点击–菜单栏下一行–Edit Widgets–退出。无效…

JDBC、datasource、数据库驱动、持久层框架之间的区别

1、jdbc Java Database Connectivity&#xff08;JDBC&#xff09;是Java平台下的一个标准API&#xff0c;它定义了一组用于连接各种数据库系统、执行SQL语句和处理结果集的接口和类。使用JDBC API&#xff0c;开发人员可以编写能够访问不同数据库系统的应用程序&#xff0c;而…

react组件传参 父传子可以传字符串,布尔值,数组,对象,jsx,

在react中&#xff0c;父传子组件 props的灵活性是很强大的&#xff0c;可以传字符串&#xff0c;布尔值&#xff0c;数组&#xff0c;对象&#xff0c;jsx&#xff0c; function Son(props) {console.log(props,"props的值")return(<div>这是儿子组件 {props.…

论文精读-SRFormer Permuted Self-Attention for Single Image Super-Resolution

论文精读-SRFormer: Permuted Self-Attention for Single Image Super-Resolution SRFormer:用于单图像超分辨率的排列自注意 Params&#xff1a;853K&#xff0c;MACs&#xff1a;236G 优点&#xff1a; 1、参考SwinIR的RSTB提出了新的网络块结构PAB&#xff08;排列自注意力…

非授权人员进入报警系统

非授权人员进入报警系统基于智能视频分析技术和深度学习技术&#xff0c;非授权人员进入报警系统通过现场已经装好的监控摄像头针对人体进行精准检测&#xff0c;并根据设置的禁入区范围进行判断。通过图像处理和人体识别算法&#xff0c;非授权人员进入报警系统可以在实时监测…

适用于当下的红色系统可视化大屏,大量图。

特定场合下使用红色系可视化大屏是可以的&#xff0c;但是千万要注意时间和场合&#xff0c;平时最好别用。

【Linux系统】文件与基础IO

本篇博客整理了文件与文件系统、文件与IO的相关知识&#xff0c;借由库函数、系统调用、硬件之间的交互、操作系统管理文件的手段等&#xff0c;旨在让读者更深刻地理解“Linux下一切皆文件”。 【Tips】文件的基本认识 文件 内容 属性。文件在创建时就有基本属性&#xff0…

简单快捷的图片格式转换工具:认识webp2jpg-online

经常写博客或记笔记的朋友们可能会碰到图床不支持的图片格式或图片太大需要压缩的情况。通常&#xff0c;我们会在浏览器中搜索在线图片格式转换器&#xff0c;但这些转换器往往伴有烦人的广告或要求登录&#xff0c;并且支持的转换格式有限。最近&#xff0c;我在浏览 GitHub …

【董晓算法】竞赛常用知识之图论2(最小环,最小生成树)

前言&#xff1a; 本系列是学习了董晓老师所讲的知识点做的笔记 董晓算法的个人空间-董晓算法个人主页-哔哩哔哩视频 (bilibili.com) 动态规划系列&#xff08;还没学完&#xff09; 【董晓算法】动态规划之线性DP问题-CSDN博客 【董晓算法】动态规划之背包DP问题&#xff…

AI交互数字人讲解员对博物馆有何价值?

近日&#xff0c;贵州省地质博物馆推出AI交互数字人贵州龙“贵贵”&#xff0c;采用垂直类大语言模型驱动&#xff0c;拥有贵地博相关专业知识&#xff0c;能够作为数字人讲解员向公众解答关于博物馆的各类问题。该AI交互数字人身着考古服装、佩戴馆徽、以可爱的小龙形象&#…

vue使用driver.js引导并自定义样式和按钮

参考网址https://driverjs.com/docs/installation 安装 npm install driver.js 以下是1.3.1版本的基本使用方法 import { driver } from driver.js import driver.js/dist/driver.css mounted() {// 实例化driver对象const driverObj driver({showProgress: true,steps: …

MQTT 5.0 报文解析 05:DISCONNECT

欢迎阅读 MQTT 5.0 报文系列 的第五篇文章。在上一篇中&#xff0c;我们已经介绍了 MQTT 5.0 的 PINGREQ 和 PINGRESP 报文。现在&#xff0c;我们将介绍下一个控制报文&#xff1a;DISCONNECT。 在 MQTT 中&#xff0c;客户端和服务端可以在断开网络连接前向对端发送一个 DIS…

Java 循环嵌套深度揭秘:挑战极限与性能优化

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 探索Java的调用栈极限 在Java中&#xff0c;方法调用是通过栈&#xff08;Stack&#xff09;这种数据结构来实现的。每当一个方法被调用时&#xff0c;一个新的栈帧&#xff08;Stack Frame&#xff09;会被创建并压…

MT3042 这项目我小码哥投了

代码 1.暴力7/15&#xff1a; #include <bits/stdc.h> using namespace std; typedef long long ll; const int N 5e6 10; int n, m; char mp[1005][1005]; int main() {cin >> n >> m;for (int i 1; i < n; i){for (int j 1; j < m; j){cin >…

【设计模式深度剖析】【A】【创建型】【对比】| 工厂模式重点理解产品族的概念

回 顾&#xff1a;创建型设计模式 1.单例模式&#x1f448;️ 2.工厂方法模式&#x1f448;️ 3.抽象工厂模式&#x1f448;️ 4.建造者模式&#x1f448;️ 5.原型模式&#x1f448;️ &#x1f448;️上一篇:原型模式 | &#x1f449;️下一篇:代理模式 目录…

2024年失业率狂飙18.1%,史上最难就业季即将来临,该如何逆袭?_2024年失业潮

【2024年被称为最难就业年&#xff0c;1158万大学生面临难题】 距离2024年毕业季还剩不到4个月&#xff0c;毕业学员将面临空前严峻的就业压力&#xff01;具国家统 计局的数据显示&#xff0c;1-2月份&#xff0c;16至24岁年轻人的失业率飙到18.1%&#xff0c;也就是说&…

WordPress建站公司模板免费下载

WordPress建站公司 适合提供WordPress建站服务的公司或个体(个人)工作室使用的WordPress建站公司主题模板。 演示 https://www.jianzhanpress.com/?p545 https://www.wpicu.com/jianzhan/ 下载 链接: https://pan.baidu.com/s/11trlwUJq_lW81R_acq4ilA 提取码: r19i

【华为】BFD与静态路由和RIP联用

【华为】BFD与静态路由和RIP联用 实验需求配置AR1AR2AR3AR4效果抓包查看 实验需求 如上图组网所示&#xff0c;在R1上配置到达R4的Loopback0。 4.4.4.4/32网段的浮动静态路由&#xff0c;正常情况下通过R3访问R4。 当R3故障时&#xff0c;自动选路通过R2访问R4的Loopback0;在R…

免费发布web APP的四个途径(Python和R)

免费发布数据分析类&#x1f310;web APP的几个途径&#x1f4f1; 数据分析类web APP目前用来部署生信工具&#xff0c;统计工具和预测模型等&#xff0c;便利快捷&#xff0c;深受大家喜爱。而一个免费的APP部署途径&#xff0c;对于开发和测试APP都是必要的。根据笔者的经验…