分类: 嵌入式
2016-05-27 17:08:36
Cpu利用率冲高定位方法:
1. 首先使用top命令查看冲高的进程/线程
1.1查看所有进程cpu占用率:
top -bn1
Mem: 3743568K used, 4283860K free, 0K shrd, 270302440K buff, 270743072K cached CPU: 33.2% usr 45.7% sys 0.0% nic 11.7% idle 0.0% io 3.4% irq 5.8% sirq /*用户空间占cpu利用率33.2%,内核占CPU利用率45.7%,nic用户进程空间内改变过优先级的进程占用CPU百分比 0.0%, id 空闲CPU百分比0.0%,*/ THREAD OFF Load average: 4.34 4.50 7.78 2/1523 3645 PID PPID USER STAT VSZ %MEM CPU %CPU COMMAND 2701 1655 root S 1454m 6.0 0 14.7 /home/RP_ROUTER/OSPFV2_COMMON_T1020_RELEASE 4 49764 1 1 2912 1655 root S 1345m 2.6 0 11.1 /home/RP_ROUTER/IPSTACK_RP_NCPAE_T1020_RELEASE 4 56791 1 1 1655 1619 root S 1065m 0.2 0 4.5 /usr/sbin/ADM_NCPAE_T1020_RELEASE 1769 1655 root S 1147m 0.4 0 2.6 /home/BASE/RMAGENT_NCPAE_T1020_RELEASE 2 43236 1 1 |
1.2输入top命令后,按数字“1”,可以显示每个CPU核的占用率
1.3输入top命令后,按”H”,可以具体显示进程下哪个线程的CPU利用率高
1.4 top –d 1,可以让刷新频率变成1秒(默认是2秒)
1.5top –bn1 显示所有进程cpu使用率
1.6.Top命令统计cpu使用率原理
在Linux/Unix下,CPU利用率(CPU utilization)分为用户态,系统态和空闲态,分别表示CPU处于用户态执行的时间,系统内核执行的时间,和空闲系统进程执行的时间。平时所说的CPU利用率是指:CPU执行非系统空闲进程的时间 / CPU总的执行时间。
在Linux的内核中,有一个全局变量:Jiffies。 Jiffies代表时间。它的单位随硬件平台的 不同而不同,系统里定义了一个常数HZ----代表每秒种最小时间间隔的数目。这样jiffies的单位就是1/HZ。Intel平台jiffies的单位是1/100秒,这就是系统所能分辨的最小时间间隔了。每个CPU时间片,Jiffies都要加1。 CPU的利用率就是用执行用户态+系统态的Jiffies除以总的Jifffies来表示。
可以用/proc/stat文件来计算cpu的利用率。这个文件包含了所有CPU活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。
如:
long@long-Ubuntu:~$ cat /proc/stat cpu 426215 701 115732 2023866 27329 4 557 0 0 0 cpu0 218177 117 57458 1013633 8620 0 6 0 0 0 cpu1 208038 584 58274 1010233 18709 4 550 0 0 0 intr 21217894 119 18974 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 146350 0 647836 370 86696 3 146156 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ctxt 38682044 btime 1362301653 processes 10118 procs_running 1 procs_blocked 0 softirq 11177991 0 6708342 2178 148765 86792 0 14537 1507468 29072 2680837 |
输出解释:
(CPU 以及CPU0、CPU1、CPU2、CPU3每行的每个参数意思(以第一行为例))
参数 |
解释 |
user (426215) |
从系统启动开始累计到当前时刻, 用户态的CPU时间 (单位:jiffies) ,不包含 nice值为负进程。1jiffies=0.01秒 |
nice (701) |
从系统启动开始累计到当前时刻, nice值为负的进程所占用的CPU时间 (单位:jiffies) |
system (115732) |
从系统启动开始累计到当前时刻, 核心时间 (单位:jiffies) |
idle (2023866) |
从系统启动开始累计到当前时刻,除硬盘IO等待时间以外 其它等待时间 (单位:jiffies) |
iowait (27329) |
从系统启动开始累计到当前时刻, 硬盘IO等待时间 (单位:jiffies) , |
irq (4) |
从系统启动开始累计到当前时刻, 硬中断时间 (单位:jiffies) |
softirq (557) |
从系统启动开始累计到当前时刻, 软中断时间 (单位:jiffies) |
CPU时间=user+system+nice+idle+iowait+irq+softirq
“intr”这行给出中断的信息,第一个为自系统启动以来,发生的所有的中断的次数;然后每个数对应一个特定的中断自系统启动以来所发生的次数。
“ctxt”给出了自系统启动以来CPU发生的上下文交换的次数。
“btime”给出了从系统启动到现在为止的时间,单位为秒。
“processes (total_forks) 自系统启动以来所创建的任务的个数目。
“procs_running”:当前运行队列的任务的数目。
“procs_blocked”:当前被阻塞的任务的数目。
那么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.确定了冲高的进程/线程后,借助gdb工具查看栈,判断是什么函数过多执行,导致cpu冲高
Gdb>thread allplay all bt
Gdb>thread 5
Gdb>bt
Gdb>f 5
3.如果发现sys cpu使用率过高,可以借助内核ftrace跟踪内核系统调用,确定是内核哪个函数耗时过多,方法如下
3.1.修改内核配置,支持trace
Kernel hacking ---> [*] Tracers --->[*] Kernel Function Tracer
[*]Kernel Function Graph Tracer
[*] Trace syscalls
[*]enable/disable function tracing dynamically
[*] Kernel function profiler
3.2.挂载trace目录
# mkdir /debug
# mount -t debugfs nodev /debug
/debug 目录下看到 tracing 目录
3.3.设备trace
#echo function > /debug/tracing/current_tracer //function为追踪的类型
#echo [pid] > /debug/tracing/set_ftrace_pid //设置要追踪的进程
#echo 1 > /debug/tracing/tracing_on //开启追踪
3.44.查看结果
#cd /debug/tracing
#cat trace