Linux问题调试(1)--CPU问题与火焰图

一、Linux CPU性能问题

在开发Linux项目的过程中,会时常出现CPU的高消耗而出现的一些异常问题。例如网络包的频繁收发引起系统阻塞,从而导致软狗超时问题等。本文总结了本人项目开发过程中使用的CPU性能调试方案。

二、Linux CPU性能查看方法

本文主要介绍三种基于Linux系统测试CPU性能的方法:TOP指令、proc/stat文件和火焰图。

1、TOP命令查看cpu性能

 top指令是‌Linux系统中用于实时监控系统状态的重要工具,能够显示系统中各个进程的资源占用情况,包括‌CPU、内存的使用情况等。执行top指令后系统的统计信息如下:

root&user1:top    //执行top指令
top - 10:54:26 up  1:08, 29 users,  load average: 25.01, 7.88, 6.01
Tasks: 544 total,   2 running, 394 sleeping,   0 stopped,   0 zombie
%Cpu(s):  8.6 us,  2.5 sy,  0.0 ni, 88.4 id,  0.3 wa,  0.0 hi,  0.2 si,  0.0 st
KiB Mem : 32929240 total, 13518068 free,  1220844 used, 18190328 buff/cache
KiB Swap:  4194300 total,  4194300 free,        0 used. 31226032 avail Mem 

  PID USER      PR  NI    VIRI    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                    
26283 root      20   0       0      0      0 I   5.6  0.0   0:00.88 [kworker/1:2]                                                                                                                                
    1 root      20   0  225816   9344   6560 S   0.0  0.0   0:04.19 /sbin/init maybe-ubiquity                                                                                                                    
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.02 [kthreadd]                                                                                                                                   
    4 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 [kworker/0:0H]                                                                                                                               
    6 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 [mm_percpu_wq]                                                                                                                               
    7 root      20   0       0      0      0 S   0.0  0.0   0:01.33 [ksoftirqd/0]                                                                                                                                
    8 root      20   0       0      0      0 I   0.0  0.0   0:04.94 [rcu_sched]              

主要关注%Cpu(S)、KiB Mem、KiB Swap和进程信息S、%CPU、%MEM.

1)%Cpu(S):8.6 us--用户空间占用CPU百分比

                        2.5 sy--内核空间占用百分比

                        88.4 id--空闲CPU百分比

2)KiB Mem:total--物料内存总量,单位B

                        free--空闲的物理内存总量

                        used--使用的物理内存总量

                        buff/cache--用作内核缓存的内存总量

3)KiB Swap:--交换区内存情况

4)S(进程状态):D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程 I=空闲

5)%CPU:上次更新到现在的CPU时间占用百分比

6)%MEM:进程使用的物理内存百分比

top命令可通过以下参数详细查看CPU性能。

top              //每隔5秒显式所有进程的资源占用情况
top -d 2         //每隔2秒显式所有进程的资源占用情况
top -c           //每隔5秒显式进程的资源占用情况,并显示进程的命令行参数(默认只有进程名)
top -Hp 进程id   // 显示某个进程下所有线程的资源占用情况
top -b           //以批次的方式执行top

2、根据 /proc/stat 文件计算cpu性能

<1>proc/stat

proc/stat节点记录的是系统进程整体的统计信息


root&user:cat /proc/stat
//CPU指标:user,nice, system, idle, iowait, irq, softirq
cpu  130216 19944 162525 1491240 3784 24749 17773 0 0 0
cpu0 40321 11452 49784 403099 2615 6076 6748 0 0 0
cpu1 26585 2425 36639 151166 404 2533 3541 0 0 0
cpu2 22555 2957 31482 152460 330 2236 2473 0 0 0
cpu3 15232 1243 20945 153740 303 1985 3432 0 0 0
cpu4 5903 595 6017 157410 30 10959 605 0 0 0
cpu5 4716 380 3794 157909 23 118 181 0 0 0
cpu6 8001 515 8995 157571 48 571 180 0 0 0
cpu7 6903 377 4869 157885 31 271 613 0 0 0
 
intr ...
ctxt 22523049
btime 1500827856
processes 23231
procs_running 1
procs_blocked 0
softirq 3552900 843593 733695 19691 93143 468832 12783 257382 610426 0 513355

CPU时间=user+system+nice+idle+iowait+irq+softirq

需要重点关注的是user、nice、system和idle:

1)user:从系统启动开始累积到当前时刻,处于用户态的运行时间,不包括 nice 值为负进程。

2)nice:从系统启动开始累积到当前时刻,nice 值为负的进程所占用的CPU时间。

3)system:从系统启动开始累积到当前时刻,处于内核态的运行时间。

4)idle:从系统启动开始累积到当前时刻,除IO等待时间外的其它等待时间。

CPU利用率可以使用以下两个方法。先取两个采样点,然后计算其差值:

cpu usage=(idle2-idle1)/(cpu2-cpu1)*100

cpu usage=[(user_2 +sys_2+nice_2) - (user_1 + sys_1+nice_1)]/(total_2 - total_1)*100

<2>/proc/<pid>/stat和/proc/<pid>/task/<tid>/stat

/proc/<pid>/stat用于获取某一个进程的统计信息;

/proc/<pid>/task/<tid>/stat用于获取某进程中某一个线程的统计信息;

root&user:cat /proc/19717/stat
19717 (sshd) S 19507 19507 19507 0 -1 4194624 200 0 0 0 0 2 0 0 20 0 1 0 738171 116998144 1418 18446744073709551615 1 1 0 0 0 0 0 4096 65536 0 0 0 17 5 0 0 0 0 0 0 0 0 0 0 0 0 0

需要重点关注的是$14--utime、$15--stime、$18--nice:

1)$14--utime:该任务在用户态运行的时间,单位为jiffies;

2)$15--stime:该任务在核心态运行的时间,单位为jiffies;

3)$18--nice:任务的静态优先级

通过执行./show_tid_stat.sh <PID>(也可使用pidof+用户进程)可打印出固定<PID>进程中各线程的CPU使用情况,将数据导出后,通过数据分析手段将数据可视化。

#!/bin/sh

#保存为show_tid_stat.sh文件用于打印固定进程中的各线程cpu使用情况
path="/proc/`$1`/task"

printf "%-10s %-32s %-20s %-20s %-20s\n" "tid" "comm" "utime" "stime" "nice"

for file in $patha/*; 
do
    echo $file
	awk '{printf("%-10s %-32s %-20s %-20s %-20s\n", $1,$2,$14,$15,$18)}' $file/stat
done

3、火焰图

火焰图(Flame Graph)是一种强大的性的性能分析工具,专门用于可视化cpu时间消耗咋各个函数栈上的情况,可以很快帮助开发这识别程序中的性能瓶颈和热点函数,从而有效的进行程序优化。火焰图通常以SVG格式提供,可以在现在浏览器中直接打开并进行交互,用户可以通过点击感兴趣的区域来查看函数名称、源码行等详细信息。

生成和创建火焰图需要如下几个步骤,具体操作在第三节中。

流程描述脚本
捕获堆栈使用 perf工具抓取程序的运行堆栈perf
折叠堆栈trace 工具抓取的系统和程序运行每一时刻的堆栈信息, 需要对他们进行分析组合, 将重复的堆栈累计在一起, 从而体现出负载和关键路径FlameGraph 中的 stackcollapse 程序
生成火焰图分析 stackcollapse 输出的堆栈信息生成火焰图flamegraph.pl

本文主要关注于liunx的CPU性能测试,使用的是on-cpu火焰图。其他火焰图(off-cpu火焰图、内存火焰图、Hot/Cold火焰图)详情可阅读:【火焰图生成与分析】_火焰图怎么分析-CSDN博客

火焰图官方博客:Flame Graphs

三、火焰图的制作

1、查找linux版本

cat /proc/version

2、查找并下载相应的linux版本

linux官网:https://www.kernel.org/

可参考#如何下载Linux源码,看这篇就够了!_linux源码下载-CSDN博客

3、解压linux压缩包

tar -zxv -f ./linux-xx.xx.xx.tar.gz -C ./

4、linux源码tools目录下编译perf工具

make ARCH=arm CROSS_COMPILE=arm-ca9-linux-gnueabihf- perf LDFLAGS+=--static NO_LIBELF=1 V=1 WERROR=0 NO_SLANG=1 NO_GTK2=1 NO_LIBAUDIT=1 NO_LIBNUMA=1 NO_LIBPERL=1 NO_STRLCPY=1

CROSS_COMPILE=/aarch64_eabi_gcc6.2.0_glibc2.24.0_fp/bin/aarch64-unknown-linux-gnueabi- 指定交叉编译器;

perf 进入perf目录编译;

LDFLAGS+=–static 静态编译 。


5、挂载到设备并执行perf采集数据(ps -T)

(1)mount
(2)./perf record -F 99 -p 1247 -g -- sleep 30

perf record 表示采集系统事件, 没有使用 -e 指定采集事件, 则默认采集 cycles(即 CPU clock 周期);

-F 99 表示每秒 99 次;

-p 1247 是进程号, 即对哪个进程进行分析;

-g 表示记录调用栈;

--sleep 30 则是持续 30 秒。

6、perf script 工具对 perf.data 进行解析

./perf script -i perf.data &> perf.unfold

7、对perf.unfold 内容中的符号进行折叠

用 stackcollapse-perf.pl 将 perf 解析出的内容 perf.unfold 中的符号进行折叠 :(需要改一下./stackcollapse-perf.p的权限chmod +x)

./stackcollapse-perf.pl perf.unfold &> perf.folded

8、生成 svg 图

需要改一下./flamegraph.pl的权限chmod +x

./flamegraph.pl .perf.folded > perf.svg

四、火焰图的分析

火焰图是基于 stack 信息生成的 SVG 图片, 用来展示 CPU 的调用栈。

  • y 轴表示调用栈, 每一层都是一个函数. 调用栈越深, 火焰就越高, 顶部就是正在执行的函数, 下方都是它的父函数.

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

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

  • 17
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值