火焰图的基本认识与绘制方法

火焰图的认识与使用-目录

  • 火焰图的基本认识
    • 火焰图有以下特征(on-cpu)
    • 火焰图能做什么
    • 火焰图类型
    • On-CPU 火焰图和Off-CPU火焰图的使用场景
    • 火焰图分析技巧
  • 如何绘制火焰图
    • 生成火焰图的流程
      • 1.生成火焰图的三个步骤
    • 安装火焰图必备工具
      • 1.安装火焰图FlameGraph脚本
      • 2.安装火焰图数据采集工具perf
        • 1. 安装perf
        • 2. 测试perf是否可用
        • 3. perf常用命令
    • 生成火焰图实践示例
      • 1.编译和执行测试程序
      • 2. perf 采集数据
      • 3.折叠堆栈
      • 4.生成火焰图
      • 5.解析火焰图含义

火焰图的基本认识

官方博客在这里插入图片描述

火焰图整个图形看起来就像一个跳动的火焰,这就是它名字的由来。

火焰图有以下特征(on-cpu)

1.每一列代表一个调用栈,每一个格子代表一个函数。
2.纵轴展示了栈的深度,按照调用关系从下到上排列。最顶上格子代表采样时,正在占用 cpu 的函数。
3.横轴的意义是指:火焰图将采集的多个调用栈信息,通过按字母横向排序的方式将众多信息聚合在一起。需要注意的是它并不代表时间。
4.横轴格子的宽度代表其在采样中出现频率,所以一个格子的宽度越大,说明它是瓶颈原因的可能性就越大。
5.火焰图格子的颜色是随机的暖色调,方便区分各个调用信息。
其他的采样方式也可以使用火焰图, on-cpu 火焰图横轴是指 cpu 占用时间,off-cpu 火焰图横轴则代表阻塞时间。
6.采样可以是单线程、多线程、多进程甚至是多 host,进阶用法可以参考附录进阶阅读。

火焰图能做什么

1.可以分析函数执行的频繁程度(占用cpu时间,或者阻塞的时间)。
2.可以分析哪些函数经常阻塞。
3.可以分析哪些函数频繁分配内存。

火焰图类型

常见的火焰图类型有 On-CPU,Off-CPU,还有 Memory,Hot/Cold,Differential 等等。它们有各自适合处
理的场景。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

On-CPU 火焰图和Off-CPU火焰图的使用场景

在这里插入图片描述
取决于当前的瓶颈到底是什么:
1.如果是 CPU 则使用 On-CPU 火焰图,(先看cpu是不是快到百分百)。
2.如果是 IO 或锁则使用 Off-CPU 火焰图(如果cpu占用率不高,就需要用off-cpu)。
3.如果无法确定, 那么可以通过压测工具来确认:
1.通过压测工具看看能否让 CPU 使用率趋于饱和, 如果能那么使用 On-CPU 火焰图
2.如果不管怎么压, CPU 使用率始终上不来, 那么多半说明程序被 IO 或锁卡住了, 此时适合使用 Off-CPU 火焰图.
4.如果还是确认不了, 那么不妨 On-CPU 火焰图和 Off-CPU 火焰图都搞搞, 正常情况下它们的差异会比较大, 如果两张火焰图长得差不多, 那么通常认为 CPU 被其它进程抢占了.

火焰图分析技巧

  1. 纵轴代表调用栈的深度(栈桢数),用于表示函数间调用关系:下面的函数是上面函数的父函数。
  2. 横轴代表调用频次,一个格子的宽度越大,越说明其可能是瓶颈原因。
  3. 不同类型火焰图适合优化的场景不同:
    1. 比如 on-cpu 火焰图适合分析 cpu 占用高的问题函数;
    2. off-cpu 火焰图适合解决阻塞和锁抢占问题。
  4. 无意义的事情:横向先后顺序是为了聚合,跟函数间依赖或调用关系无关;火焰图各种颜色是为方便区
    分,本身不具有特殊含义
  5. 多练习:进行性能优化有意识的使用火焰图的方式进行性能调优(如果时间充裕)

如何绘制火焰图

注意:采集需要ROOT权限

生成火焰图的流程

1.生成火焰图的三个步骤

在这里插入图片描述

安装火焰图必备工具

1.安装火焰图FlameGraph脚本

1.Brendan D. Gregg 的 Flame Graph 工程实现了一套生成火焰图的脚本。Flame Graph 项目位于 GitHub上:git clone https://github.com/brendangregg/FlameGraph.git
2.使用码云gitee的链接:git clone https://gitee.com/mirrors/FlameGraph.git
用 git 将其 clone下来
记住git clone时 FlameGraph 的路径,绘制火焰图时需要
在这里插入图片描述

不同的 trace 工具抓取到的信息不同, 因此 Flame Graph 提供了一系列的 stackcollapse(堆栈折叠) 工具.

查看帮助 ./FlameGraph/flamegraph.pl -h==

2.安装火焰图数据采集工具perf

1.系统级性能优化通常包括两个阶段:性能剖析(performance profiling)和代码优化:
(1).性能剖析的目标是寻找性能瓶颈,查找引发性能问题的原因及热点代码。
(2).代码优化的目标是针对具体性能问题而优化代码或编译选项,以改善软件性能。一般在工作中比较关心的是性能瓶颈,特别是算法。
2.当在系统全功能启动的时候,算法一般需要将设备的性能用到极限,而在这个过程中不免出现各类性能上的瓶颈,此时需要分析自身的一些性能瓶颈在什么地方就可以用到专门的性能分析工具perf。
3.perf 命令(performance profiling的缩写), 它是 Linux 系统原生提供的性能分析工具, 会返回 CPU 正在执行的函数名以及调用栈(stack)
具体用法:
perf Examples
Linux kernel profiling with perf
Linux Performance (brendangregg.com)
perf的原理:
每隔一个固定的时间,就在CPU上(每个核上都有)产生一个中断,在中断上看看,当前是哪个pid,哪个函数,然后给对应的pid和函数加一个统计值,这样,我们就知道CPU有百分几的时间在某个pid,或者某个函数上了。
这个原理图示如下:1秒采集99次,1秒采集1000次(采样次数越高容易影响程序性能)
在这里插入图片描述
很明显可以看出,这是一种采样的模式,预期:运行时间越多的函数,被时钟中断击中的机会越大,从而推测,那个函数(或者pid等)的CPU占用率就越高
这种方式可以推广到各种事件,比如ftrace的事件,你可以在这个事件发生的时候上来冒个头,看看击中了谁,然后算出分布,我们就知道谁会引发特别多的那个事件了。
当然,如果某个进程运气特别好,它每次都刚好躲过你发起探测的位置(这时候就需要考虑提高采样频率),你的统计结果可能就完全是错的了。这是所有采样统计都有可能遇到的问题了。

1. 安装perf

安装需要root权限(比如Ubuntu通过sudo su切换到root权限),perf 采集的时候也需要root的权限
apt install linux-tools-common

2. 测试perf是否可用

perf record -F 99 -a -g -- sleep 10
出现报错:

WARNING: perf not found for kernel 5.15.0-89

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

You may also want to install one of the following packages to keep up to date:
linux-tools-generic
linux-cloud-tools-generic
在这里插入图片描述

则需要安装linux-tools-generic和linux-cloud-tools-generic,但需选择对应的版本,比如提示的是5.15.0-89,则我们安装5.15.0-89版本:
apt-get install linux-tools-4.15.0-48-generic linux-cloud-tools-4.15.0-48-generic linux-tools-generic linux-cloud-tools-generic

再次测试 perf record -F 99 -a -g -- sleep 10
如果没有报错则在执行测试命令的目录产生 perf.data 文件
在这里插入图片描述

3. perf常用命令

查看帮助文档,perf功能非常强大,我们这里只关注record和report功能,record和report也可以继续通过二级命令查询帮助文档。
perf -h

usage: perf [--version] [--help] [OPTIONS] COMMAND [ARGS]The most commonly used perf commands are:annotate        Read perf.data (created by perf record) and display annotated codearchive         Create archive with object files with build-ids found in perf.data filebench           General framework for benchmark suitesbuildid-cache   Manage build-id cache.buildid-list    List the buildids in a perf.data filec2c             Shared Data C2C/HITM Analyzer.config          Get and set variables in a configuration file.daemon          Run record sessions on backgrounddata            Data file related processingdiff            Read perf.data files and display the differential profileevlist          List the event names in a perf.data fileftrace          simple wrapper for kernel's ftrace functionalityinject          Filter to augment the events stream with additional informationiostat          Show I/O performance metricskallsyms        Searches running kernel for symbolskmem            Tool to trace/measure kernel memory propertieskvm             Tool to trace/measure kvm guest oslist            List all symbolic event typeslock            Analyze lock eventsmem             Profile memory accessesrecord          Run a command and record its profile into perf.datareport          Read perf.data (created by perf record) and display the profilesched           Tool to trace/measure scheduler properties (latencies)script          Read perf.data (created by perf record) and display trace outputstat            Run a command and gather performance counter statisticstest            Runs sanity tests.timechart       Tool to visualize total system behavior during a workloadtop             System profiling tool.version         display the version of perf binaryprobe           Define new dynamic tracepointstrace           strace inspired toolSee 'perf help COMMAND' for more information on a specific command.

常用的五个命令:

perf list:查看当前软硬件环境支持的性能事件
perf stat:分析指定程序的性能概况
perf top:实时显示系统/进程的性能统计信息
perf record:记录一段时间内系统/进程的性能事件
perf report:读取perf record生成的perf.data文件,并显示分析数据(生成火焰图用的采集命令)

perf record -h
常用命令

-e :指定性能事件(可以是多个,用,分隔列表)
-p :指定待分析进程的 pid(可以是多个,用,分隔列表, nginx , -p 100,101,102,103)
-t :指定待分析线程的 tid(可以是多个,用,分隔列表)
-u :指定收集的用户数据,uid为名称或数字
-a:从所有 CPU 收集系统数据
-g:开启 call-graph (stack chain/backtrace) 记录(backtrace调试功能的实现原理就是利用函数调用
栈中的信息来追踪程序执行的路径和调用关系。)
-C :只统计指定 CPU 列表的数据,如:0,1,3或1-2
-r :perf 程序以SCHED_FIFO实时优先级RT priority运行这里填入的数值越大,进程优先级越高(即
nice 值越小)
-c : 事件每发生 count 次采一次样
-F :每秒采样 n 次
-o <output.data>:指定输出文件output.data,默认输出到perf.data

perf report -h

-i, --input input file name,可以指定要分析的文件名,默认perf.data

生成火焰图实践示例

我们需要先写个简单的测试程序,分main、func_a、func_b、func_c、func_d 5个函数:
main: 调用func_a、func_b、func_c
func_a:调用func_d
这里的目的是演示宽度对应函数占用的cpu时间。

1.编译和执行测试程序

源码:test.c

#include <stdio.h>
void func_d()
{for (int i = 5 * 10000; i--;);
}
void func_a()
{for (int i = 10 * 10000; i--;);
func_d();
}
void func_b()
{for (int i = 20 * 10000; i--;);
}
void func_c()
{for (int i = 35 * 10000; i--;);
}
int main(void)
{printf("main into\n");while (1){for (int i = 30 * 10000; i--;);func_a();func_b();func_c();}printf("main end\n");return 0;
}

该程序用于生成测试程序。
编译:gcc -o test test.c
执行:./test
在这里插入图片描述

2. perf 采集数据

通过top指令查看test的pid:perf record -F 99 -p 42850 -g -- sleep 30
perf record 表示采集系统事件, 没有使用 -e 指定采集事件, 则默认采集 cycles(即 CPU clock 周期), -F 99 表示每秒 99 次,-p 42850 是进程号, 即对哪个进程进行分析, -g 表示记录调用栈, sleep 30 则是持续 30 秒.

-F 指定采样频率为 99Hz(每秒99次), 如果 99次 都返回同一个函数名, 那就说明 CPU 这一秒钟都在执行同一个函数, 可能存在性能问题.

为了便于阅读, perf record 命令可以统计每个调用栈出现的百分比, 然后从高到低排列.
perf report -n --stdio

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

Samples:采样个数
Event count:系统总共发生的事件数
Symbol:函数名,其中 [.] 表示用户空间函数,[k] 表示内核函数
Shared Objec:函数所在的共享库或所在的程序
Command:进程名
Self:该函数的 CPU 使用率
Children:该函数的子函数的 CPU 使用率

# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 2K of event 'cpu-clock:pppH'
# Event count (approx.): 29808080510
#
# Children      Self       Samples  Command  Shared Object      Symbol               >
# ........  ........  ............  .......  .................  .....................>
#100.00%     0.00%             0  test     libc.so.6          [.] 0x00007f05395b6d90|---0x7f05395b6d90main|          |--34.80%--func_c|          |--20.70%--func_b|          --14.33%--func_a|          --5.05%--func_d100.00%    30.13%           889  test     test               [.] main|          |--69.87%--main|          |          |          |--34.80%--func_c|          |          |          |--20.70%--func_b|          |          |           --14.33%--func_a|                     |          |                      --5.05%--func_d|          --30.13%--0x7f05395b6d90main34.80%    34.73%          1025  test     test               [.] func_c|          --34.73%--0x7f05395b6d90mainfunc_c20.70%    20.67%           610  test     test               [.] func_b|          --20.67%--0x7f05395b6d90mainfunc_b14.33%     9.28%           274  test     test               [.] func_a|          |--9.28%--0x7f05395b6d90|          main|          func_a|          --5.05%--func_afunc_d5.05%     5.05%           149  test     test               [.] func_d|---0x7f05395b6d90mainfunc_afunc_d

3.折叠堆栈

  1. 首先用perf script 工具对 perf.data 进行解析
    生成折叠后的调用栈:perf script -i perf.data &> perf.unfold
    在这里插入图片描述
  2. 然后将解析出来的信息存下来, 供生成火焰图
    用 stackcollapse-perf.pl 将 perf 解析出的内容 perf.unfold 中的符号进行折叠 :./FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
    注意: ./FlameGraph/stackcollapse-perf.pl路径为自己的路径,根据自己的情况进行修改
    #生成火焰图需要的统计信息

4.生成火焰图

最后生成 svg 图-绘制火焰图:
注意: ./FlameGraph/flamegraph.pl路径为自己的路径,根据自己的情况进行修改
./FlameGraph/flamegraph.pl perf.folded > test_oncpu.svg
我们也可以使用管道将上面的流程简化为一条命令:
注意: ./FlameGraph/stackcollapse-perf.pl路径为自己的路径,根据自己的情况进行修改
perf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > test_oncpu.svg

perf script默认是输入perf.data,如果需要指明输入数据用perf script -i xxx

5.解析火焰图含义

最后就可以用浏览器打开火焰图进行分析啦.
在这里插入图片描述

火焰图是基于 stack 信息生成的 SVG 图片, 用来展示 CPU 的调用栈。
1.y 轴表示调用栈, 每一层都是一个函数. 调用栈越深, 火焰就越高, 顶部就是正在执行的函数, 下方都是它的父函数.
2.x 轴表示抽样数, 如果一个函数在 x 轴占据的宽度越宽, 就表示它被抽到的次数多, 即执行的时间长. 注意,x 轴不代表时间, 而是所有的调用栈合并后, 按字母顺序排列的.
3.火焰图就是看顶层的哪个函数占据的宽度最大. 只要有 “平顶”(plateaus), 就表示该函数可能存在性能问题。
4.颜色没有特殊含义, 因为火焰图表示的是 CPU 的繁忙程度, 所以一般选择暖色调.

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

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

相关文章

智能优化算法应用:基于人工水母算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于人工水母算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于人工水母算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工水母算法4.实验参数设定5.算法结果6.参考…

4 STM32MP1 Linux系统启动过程

1. ROM代码 这是ST官方写的代码&#xff0c;在STM32MP1出厂时就已经烧录进去&#xff0c;不能被修改。ROM代码是上电以后首先执行的程序&#xff0c;它的主要工作就是读取STM32MP1的BOOT引脚电平&#xff0c;然后根据电平来判断当前启动设备&#xff0c;最后从选定的启动设备里…

快速认识,后端王者语言:Java

Java作为最热门的开发语言之一&#xff0c;长居各类排行榜的前三。所以&#xff0c;就算你目前不是用Java开发&#xff0c;你应该了解Java语言的特点&#xff0c;能用来做什么&#xff0c;以备不时之需。 Java 是一种高级、多范式编程语言&#xff0c;以其编译为独立于平台的字…

快手数仓面试题附答案

题目 1 讲一下你门公司的大数据项目架构&#xff1f;2 你在工作中都负责哪一部分3 spark提交一个程序的整体执行流程4 spark常用算子列几个&#xff0c;6到8个吧5 transformation跟action算子的区别6 map和flatmap算子的区别7 自定义udf&#xff0c;udtf&#xff0c;udaf讲一下…

Java链接数据库

本文介绍的是Java链接数据库中的JDBC操作&#xff0c;JDBC虽然现在用的不多&#xff0c;但面试的时候会问道。需要有相应的了解。下面以链接MySQL为例子。 JDBC 什么jdbc Java DataBase Connectivity是一种用于执行SQL语句的Java API&#xff0c;它由一组用Java语言编写的类和…

初识Protobuf与Protobuf的安装

目录 一、Protobuf 1.回顾序列化 2.Protobuf的特性 3.Protobuf的下载 ①ProtoBuf 在 window 下的安装 ②ProtoBuf 在 Linux 下的安装 一、Protobuf 1.回顾序列化 我们在先前的学习中也遇到过序列化。所谓序列化我的理解是&#xff0c;将复杂的对象以特定的方式转换以便于…

【计算机网络笔记】物理层——信道与信道容量

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

【稳定检索|投稿优惠】2024年光电信息与机器人发展国际会议(ICOIRD 2024)

2024年光电信息与机器人发展国际会议(ICOIRD 2024) 2024 International Conference on Optoelectronic Information and Robot Development(ICOIRD 2024) 一、【会议简介】 信息技术与人工智能的浪潮正在激荡&#xff0c;不断刷新我们生活的页面&#xff0c;深刻烙印在光电信息…

Homework 3: Higher-Order Functions, Self Reference, Recursion, Tree Recursion

Q1: Compose 编写一个高阶函数composer&#xff0c;它返回两个函数func和func_adder。 func是一个单参数函数&#xff0c;它应用到目前为止已经组合的所有函数。这些函数将首先应用最新的函数&#xff08;参见doctests和示例&#xff09;。 func_adder用于向我们的组合添加更多…

“快慢指针”思想在物理或者逻辑循环中的应用

1 基础概念 1.1 什么是物理循环和逻辑循环&#xff1f; 物理循环是指物理索引访问顺序上相邻&#xff0c;逻辑上也相邻&#xff0c;比如循环链表&#xff0c;逻辑循环则指物理的索引上不一定相邻 1.2 快慢指针本质上可以解决逻辑循环问题&#xff0c;而物理循环也属于逻辑循…

用AI在抖音直播做姓氏头像的全新玩法,详细分析制作教程

前段时间在圈子里给大家分享了用AI写艺术字做小红书账号案例玩法&#xff0c;同学们都比较热衷学习。纷纷动手实践。 事实上用AI艺术字变现玩法还有许多。 例如上周末在星球给圈友们分享的一个AI艺术字直播的抖音账号&#xff0c;直播内容形式很简单&#xff0c;就是展现用AI…

七大经典高效学习方法

金字塔学习模型 金字塔学习是美国学习专家爱德加戴尔1946年提出的。 他将学习分为主动学习和被动学习两种类型&#xff0c;用数字形象地呈现了采用不同学习方式&#xff0c;学习者在两周后还能记住的内容有多少。 被动学习&#xff1a;通过听讲、阅读、视听、演示这些活动&a…

Java网络编程——基础入门

1、进程间的通信 进程指运行中的程序&#xff0c;进程的任务就是执行程序中的代码。EchoPlayer类是一个独立的Java程序&#xff0c;它可以在任意一台安装了JDK的主机上运行&#xff1a; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStr…

Linux socket编程(11):Unix套接字编程及通信例子

Unix套接字是一种用于在同一台计算机上的进程间通信的一种机制。它是Linux和其他类Unix系统中的一项特性&#xff0c;通过在文件系统中创建特殊的套接字文件&#xff0c;进程可以通过这些套接字文件进行通信。 文章目录 1 Unix和TCP套接字对比2 Unix套接字初始化流程3 例:服务端…

3.4 路由器的DHCP配置

实验3.4 路由器的DHCP配置 一、任务描述二、任务分析三、具体要求四、实验拓扑五、任务实施&#xff08;一&#xff09;配置基于接口地址池的DHCP1.交换机的基本配置2.路由器的基本配置3.开启路由器的DHCP服务器功能4.配置路由器接口的DHCP功能5.设置计算机使用DHCP方式获取IP地…

DS图应用--最短路径

Description 给出一个图的邻接矩阵&#xff0c;再给出指定顶点v0&#xff0c;求顶点v0到其他顶点的最短路径 Input 第一行输入t&#xff0c;表示有t个测试实例 第二行输入n&#xff0c;表示第1个图有n个结点 第三行起&#xff0c;每行输入邻接矩阵的一行&#xff0c;以此类…

Hello World!

一、minist数据集 深度学习编程特有的hello world程序&#xff1a;采用minist数据集完成意向特定深度学习项目 1、minist数据集介绍 MNIST数据集是一个广泛使用的手写数字识别数据集&#xff0c;它包含了许多不同人手写的数字图片。这个数据集被广泛用于研究手写数字识别&…

通过keepalived+nginx实现 k8s apiserver节点高可用

一、环境准备 K8s 主机配置&#xff1a; 配置&#xff1a; 4Gib 内存/4vCPU/60G 硬盘 网络&#xff1a;机器相互可以通信 k8s 实验环境网络规划&#xff1a; podSubnet&#xff08;pod 网段&#xff09; 10.244.0.0/16 serviceSubnet&#xff08;service 网段&#xff09;: 1…

【S32K3环境搭建】-0.2-安装S32DS product updates和 packages

目录 1 安装S32DS product updates和 packages 1.1 方法一&#xff1a;通过S32DS Extensions and Updates安装product updates和 packages 1.2 方法二&#xff1a;通过Install New Software…安装product updates和 packages 2 S32DS product updates和 packages安装后的效…

海外服务器和国内服务器有什么样的区别呢

海外服务器和国内服务器有什么样的区别呢&#xff0c;其实呢在外形方面是大同小异&#xff0c;除了外形还有一些其他方面还存在这一些差异。 一&#xff0c;地理位置的差异。 海外服务器——有可能在中国数据中心之外的任何国家地区&#xff0c;例如美国服务器&#xff0c;韩…