火焰图性能监测

准备工作——安装perf

我是在github的codespace上搞的,可以按下面的方式安装perf:

sudo apt install linux-tools-generic
sudo apt install linux-cloud-tools-azure

参考在WSL2中使用perf性能剖析工具

测试程序——简单的C程序

弄一个无限循环的C程序进行测试:

// main.c
#include<stdio.h>

int add(int a, int b){ return a + b; }

int sub(int a, int b){ return a - b; }

int main(){
    while(1){
        sub(add(3, 4), 5);
    }
    return 0;
}

编译成可执行文件gcc main.c -o main并运行。
获取这个进程的pid,用htop命令查看一下./main对应的进程:
在这里插入图片描述
这里对应的pid是19647

监测并生成火焰图

使用perf程序进行监测:

sudo perf record -F 99 -p 19647 -a -g -- sleep 10 

这里将采样频率设置为99次/秒,最高好像是100次,为保证准确,一般设置为99次。

该命令会生成perf.data文件,记录了进程的函数调用情况,随后从github将FlameGraph克隆到本地,执行如下命令:

sudo perf script > out.perf
../FlameGraph/stackcollapse-perf.pl out.perf > out.folded
./FlameGraph/flamegraph.pl out.folded > "./flamegraph.svg"

生成的./flamegraph.svg可以在vscode中使用扩展SVG进行预览,右击./flamegraph.svg进行预览就出来了,还是很方便的。

生成火焰图如下:

我们的主要函数依然是main,add,sub,在编译的过程中,他们的名称可能改变,比如C++中可能会添加前缀或下划线什么的。其中add和sub函数占用最多的计算资源,两者的比例分别为24.69%和30.04%,采样次数分别为2,293,939,370次和3,494,949,460次,在以效率著称的C语言中这很明显。

后面我测了一下python,相同的代码,add和sub分别被改名为long_add和long_sub,而两者占用的时间比例仅为1.12%和1.22%!!!采样次数分别为111,111,110次和131,313,130次。这里采样的时间是相同的,均为10s。python做了挺多额外工作的,毕竟是解释型语言,python脚本并不直接作为程序,而是作为解释器的一部分(不过也可以用编译的方式来运行)。

python程序用perf生成的火焰图里面的名字会变得很奇怪,甚至不知道对应的是什么函数,用py-spy工具会好一些。这个工具很方便,通过pip install py-spy即可安装,然后通过py-spy record --pid 130526 -o out.svg 就可以直接生成火焰图,很便捷。

这里要注意以下采样次数的意思,类似于频率的意思,采样是每隔一小段时间观测一下,如果这次观测中监测到了sub函数,则sub函数的次数加一。sub(3,494,949,460 samples, 30.04%),表示在10s内遇到过这个函数3,494,949,460次。由于是隔一段时间采样一下,所以难免有遗漏,但在大量的采用中还是具有统计意义的。

这在add和sub函数之后还有一些冒尖的函数,放大左右两边冒尖的函数情况如下:
在这里插入图片描述
虽然我们的C测试程序主要是main,add,sub三个函数,但编译链接的过程中,会将其他相关的包链接到程序中,使程序中的符号增加。所以程序执行的过程中,还会涉及到其他的一些函数,比如上面的asm_sysvec_reschedule_ipi 用于处理系统调度的中断处理函数。它负责在特定的时间间隔内触发调度器,使得其他进程有机会运行。
exit_to_user_mode_prepare用于准备切换到用户模式的操作。在操作系统中,内核和用户模式之间的切换需要进行一些准备工作,这个函数就负责执行这些准备操作。

因为这个进程是开始一段时间后再监测的,所以有一些函数没有抓取到,通过readelf命令,我们可以看到main可执行文件中涉及到的所有符号:

$ readelf main -s

Symbol table '.dynsym' contains 6 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)
     3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
     5: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 64 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000318     0 SECTION LOCAL  DEFAULT    1 
     2: 0000000000000338     0 SECTION LOCAL  DEFAULT    2 
	...
    58: 0000000000004010     0 NOTYPE  GLOBAL DEFAULT   24 __bss_start
    59: 0000000000001157    37 FUNC    GLOBAL DEFAULT   14 main
    60: 0000000000004010     0 OBJECT  GLOBAL HIDDEN    23 __TMC_END__
    61: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
    62: 0000000000001141    22 FUNC    GLOBAL DEFAULT   14 sub
    63: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@@GLIBC_2.2

如果要了解进程更详细的情况,还可以去/proc文件夹下面看看,每个进程都建立了对应的一个文件夹,文件夹名称对应进程的pid。
比如通过ll /proc/19647/cwd可以查看该进程的工作目录,通过ll /proc/19647/exe可以查看该进程对应的执行文件。

最后,为便于下次使用,我将生成火焰图的过程整理成脚本perf.sh,直接执行bash perf.sh pid就好了,生成的火焰图文件名为flamegraph_pid_$pid.svgperf.sh脚本内容如下:

#!/bin/bash

# Check if the number of arguments is correct
if [ $# -ne 1 ]; then
    echo "Usage: $0 <pid>"
    exit 1
fi

pid=$1
mkdir -p temp

# Check if FlameGraph folder exists
if [ ! -d "FlameGraph" ]; then
    # Clone FlameGraph repository
    git clone https://github.com/brendangregg/FlameGraph.git
fi

cd temp || exit
sudo perf record -F 99 -p $pid -a -g -- sleep 10 
sudo perf script > out.perf
current_time=$(date + "%Y%m%d%H%M%S")
mv perf.data "perf_pid_${pid}_$current_time.data"

../FlameGraph/stackcollapse-perf.pl out.perf > out.folded
../FlameGraph/flamegraph.pl out.folded > "../flamegraph_pid_$pid.svg"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 基于STM32火焰传感器原理,我会分为三个部分进行回答。 首先,STM32是一款集成了ARM Cortex-M内核的微控制器。它具有良好的性能和丰富的外设接口,适合用于各种传感器的应用。 其次,火焰传感器是一种用于检测火焰的传感器。它能够感知到火焰电离产生的电离子,从而判断是否存在火焰火焰传感器通常由感光元件、模拟信号处理电路和数字信号处理电路等部分组成。 在STM32火焰传感器原理中,可能会包含以下主要部件。首先是火焰传感器感光元件,它能够接收到火焰产生的光信号,并转换为电信号。其次是模拟信号处理电路,用于将感光元件输出的电信号放大和滤波,以便对信号进行后续的处理。再次是AD转换电路,用于将模拟信号转换为数字信号,以供STM32微控制器进行数字信号处理。最后是STM32微控制器,它可以通过内置的模拟输入引脚接收数字信号,并结合程序进行处理和判断。当检测到火焰时,STM32可以输出相关信号,如蜂鸣器报警或通过通信接口发送消息。 综上所述,基于STM32火焰传感器原理可以实现对火焰的检测和处理。通过合理的电路设计和程序编写,可以实现对火焰的精准检测以及相关应用的实现,如火灾报警系统等。 ### 回答2: 基于STM32火焰传感器原理的设计可以实现火焰的检测功能。该原理主要涉及以下几个模块的设计。 首先是火焰传感器模块,该模块通过火焰传感器接收到的光信号来判断周围是否有火焰。传感器通常采用光敏电阻或红外线传感器等技术,能够检测到火焰发射的辐射光。当检测到火焰时,传感器会输出一个电压信号。 其次是模拟信号处理模块,该模块用来对传感器输出的电压信号进行放大、滤波和采样等处理。这样可以提高信号的准确性和稳定性,使其适合于后续数字信号处理。 然后是模数转换模块(ADC),该模块将模拟电压信号转换为数字信号,以便于处理器进行数字信号处理。ADC采样的位数越高,转换精度越高,能够更准确地检测到火焰的存在。 最后是STM32微控制器,该控制器接收ADC模块转换得到的数字信号,并进行相应的处理。根据预设的阈值判断火焰是否存在,可以通过控制输出引脚触发报警装置或者进行其他操作。 总体而言,基于STM32火焰传感器原理的设计实现了对火焰的检测功能,并能够通过控制器进行相应的处理和操作。这样的设计在火灾预防等领域具有重要的应用价值。 ### 回答3: STM32火焰传感器原理是一种使用STM32微控制器和火焰传感器构建的电路。该原理的目的是实时检测周围环境中的火焰,并采取相应的措施来保护设备或人员的安全。 在该原理中,STM32微控制器与火焰传感器通过GPIO引脚相连接。火焰传感器是一种能够检测光源和火焰的传感器。它使用光敏电阻或光敏二极管来感知周围环境中的火焰光源。当探测到火焰存在时,火焰传感器会产生一个信号,并将其发送到STM32微控制器。 STM32微控制器接收到火焰传感器的信号后,会相应地执行预设的程序。比如,它可以触发警报系统,以提醒人们火灾的发生,或者自动触发灭火系统以控制火焰的蔓延。同时,它也可以将火焰传感器检测到的数据存储到存储器中,以供后续分析和报告。 为了确保系统的稳定性和可靠性,原理还可能包括一些其他的组件,如电源管理电路、信号放大器、采样电路和保护电路等。这些组件可以帮助确保火焰传感器的精确度和灵敏度,并提供稳定的电源和保护功能。 总之,STM32火焰传感器原理是基于STM32微控制器和火焰传感器构建的电路,用于实时检测和应对火灾威胁。它可以提供可靠的火灾监测和保护,并在检测到火焰时采取适当的措施保护设备和人员的安全。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值