编者注: 本来想写个简单的程序测试CPU利用率,后来代码实现后与top(ps)命令测试的结果做对比,疑惑了,疑惑后有了此文……
本来就是想通过写个小程序测试CPU利用率从而可以检验其他的工具性能之类的数据,后来参照IPbench中的cpu_target_lukem插件实现我们的功能,原理很简单:就是我们给程序设置了极低的优先级,如果有任何计算任务都会打断它,而如果没有计算任务,我们的程序就会占用cpu时间,所以我们的程序的运行时间基本上可以算作CPU的闲暇时间。
所以我们计算总的CPU利用率的方法就是 : CPU利用率 = 1 - 程序占用cpu时间/程序总的运行时间。
主要功能实现代码如下:
x0 = get_cycles(); //last cycle count values
while (calc) {
x1 = x0; //last cycle count values gives to x1
x0 = get_cycles(); //the current count values
delta = x0 - x1; // ∆t
total += delta; //adds ∆t to a running total
/* If the delta looks like less than a context switch,add this to idle time; otherwise add it to busy time */
if (delta < PROFILE_CONTEXT_COST)
idle += delta;
timer_buffer.idle = idle;
timer_buffer.total = total;
}
之后我们编译运行本程序,程序输出为:
[11:43.32] dbg: Average CPU time is 5.2
[11:43.34] dbg: Average CPU time is 5.2
这时候我们使用 " ps -au "命令,会找到这一条信息:
long 11741 95.7 0.0 19668 520 pts/16 SNl+ 11:40 2:58 ./a.out
熟悉ps命令的童鞋们知道,long为该进程所属用户;11741为该进程的PID号;95.7表示该进程的CPU占用率为95.7%;0.0表示该进程的物理内存占用率为0%;19668表示该进程占用了多少虚拟内存量;520表示该进程占用了多少固定内存量;pts/16表示登陆端口;SNl+为和上面介绍的进程状态一样(R/S/D/T/Z进程);11:40为该进程触发启动的时间; 2:58表示该进程占用CPU的时间;./a.out表示触动该进程的命令 。
所以ps命令显示的是我们a.out的CPU利用率高达95.7%(也就是说95.7%CPU都是闲暇的,所以我们的程序测得CPU利用率为5.2% 也相差不大)。
接着,我做了第二个测试,我把a.out拷贝了一份b.out,同时运行他们我们会看到如下信息:
a.out 显示的 :
[11:47.50] dbg: Average CPU time is 6.1
[11:47.52] dbg: Average CPU time is 6.1
b.out 显示的s :
[11:48.20] dbg: Average CPU time is 10.2
[11:48.22] dbg: Average CPU time is 10.2
这时候我使用 "ps -au" 再查看a.out和b.out信息如下:
long 11741 94.1 0.0 19668 520 pts/16 SNl+ 11:40 7:26 ./a.out
long 11905 90.9 0.0 19668 516 pts/17 SNl+ 11:46 2:08 ./b.out
卧槽,顿时崩溃啊!到了这,我产生了三个疑问:第一、为毛运行a.out和b.out显示的CPU利用率不一样……第二、为毛在ps中显示的a.out和b.out的CPU利用率不一样?第三、为毛ps中a.out和b.out的CPU利用率分别为94.1%和90.0%,而两者加一起远远大于100%?!!我晕了,那Linux到底是如何定义CPU利用率的呢?
long@long-Ubuntu:~$ top
top - 20:12:45 up 3:05, 6 users, load average: 1.16, 1.27, 1.14
Tasks: 208 total, 1 running, 206 sleeping, 0 stopped, 1 zombie
%Cpu(s): 11.8 us, 3.7 sy, 0.0 ni, 84.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 2067372 total, 1998832 used, 68540 free, 54104 buffers
KiB Swap: 2095100 total, 25540 used, 2069560 free, 449612 cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
6635 long 20 0 435m 79m 32m S 7.3 3.9 11:31.39 rhythmbox
4523 root 20 0 110m 61m 4804 S 5.3 3.0 8:34.14 Xorg
5316 long 9 -11 162m 5084 4088 S 4.3 0.2 6:01.53 pulseaudio
5793 long 20 0 114m 22m 13m S 4.3 1.1 0:23.38 gnome-terminal
……
在第一行的最后显示的为 “ load average: 1.16 , 1.27 ,1.14”long@long-Ubuntu:~$ uptime
20:15:01 up 3:07, 6 users, load average: 0.43, 0.97, 1.05
这三个数分别是:一分钟内、五分钟内、十五分钟内的系统负载均值。也就是说,从右向左看这几个数据,我们可以判断系统负载的发展趋势。
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
参数 | 解释 |
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) |
实际上,这些问题感觉很诡异,但是经过我一番学习之后,发现,答案其实很简单。
首先,为啥a.out和b.out显示的CPU利用率不一样?在我问我们老师Nicholas Mc Guire的邮件上,他回复“cpu utilization is a per cpu value of how much time the CPU is spending with process X” 也就是说CPU利用率是一个程序占用一个CPU处理器多少时间的百分比值!(他说的是某个进程占有的CPU利用率,如top上显示的!而我想要算的是总的的CPU利用率,但是他提到了process X !也就是说,如上面的双处理器的负载满额的情况是 2.00,我的机器是双核,所以,这里a.out和b.out算得分别是两个CPU核心上的利用率!)
而经过一段时间后,a.out和b.out显示的值都会很接近!因为,双核的计算任务不可能相差很大的!
如某一时间,a.out显示如下:
[15:50.31] dbg: Average CPU time is 13.2
[15:50.33] dbg: Average CPU time is 13.2
此时b.out显示如下:
[15:50.31] dbg: Average CPU time is 13.0
[15:50.33] dbg: Average CPU time is 13.0
而,此时top结果:
long@long-Ubuntu:~$ top
top - 15:40:31 up 7:01, 6 users, load average: 2.20, 2.40, 2.31
Tasks: 208 total, 1 running, 206 sleeping, 0 stopped, 1 zombie
%Cpu(s): 4.0 us, 1.2 sy, 94.9 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 2067372 total, 1970184 used, 97188 free, 20812 buffers
KiB Swap: 2095100 total, 72400 used, 2022700 free, 449896 cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
14944 long 39 19 19668 520 432 S 91.3 0.0 34:07.64 a.out
14952 long 39 19 19668 516 432 S 90.7 0.0 33:54.69 b.out
4597 root 20 0 99396 35m 5620 S 3.3 1.8 27:26.09 Xorg
如果我把a.out再拷贝两个副本分别叫c.out和d.out,那么top命令下,显示如下所示,a.out和b.out原来分别占90%左右,现在a.out、b.out、c.out和d.out则分别占40%左右,我们可以理解成,原先a.out占用cpu0的90%空闲时间(上文已经提到:因为我们的程序就是设置了极低的优先级,如果有任何计算任务都会打断,而如果没有计算任务,我们的程序就会占用cpu时间,所以占用的都是空间时间),而b.out占用cpu1的90%空闲时间,而现在c.out和a.out平分了cpu0的这90%空闲时间,d.out和b.out平分了cpu1的这90%空闲时间,所以,a.out、b.out、c.out和d.out此时的CPU利用率则分别占40%左右。
long@long-Ubuntu:~$ top
top - 15:53:44 up 7:14, 8 users, load average: 3.76, 3.01, 2.65
Tasks: 213 total, 1 running, 211 sleeping, 0 stopped, 1 zombie
%Cpu(s): 21.7 us, 9.5 sy, 68.8 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 2067372 total, 1981532 used, 85840 free, 18416 buffers
KiB Swap: 2095100 total, 75832 used, 2019268 free, 415140 cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
14944 long 39 19 19668 520 432 S 37.5 0.0 45:04.77 a.out
15856 long 39 19 19668 516 432 S 33.2 0.0 0:23.74 d.out
14952 long 39 19 19668 516 432 S 32.8 0.0 44:52.23 b.out
15803 long 39 19 19668 516 432 S 31.5 0.0 0:25.49 c.out
5297 long 20 0 251m 75m 20m S 20.2 3.7 15:53.31 compiz
long@long-Ubuntu:~$ top
top - 14:52:24 up 6:13, 5 users, load average: 1.06, 1.02, 1.24
Tasks: 203 total, 1 running, 201 sleeping, 0 stopped, 1 zombie
%Cpu(s): 27.5 us, 5.9 sy, 0.0 ni, 66.2 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 2067372 total, 1808288 used, 259084 free, 41020 buffers
KiB Swap: 2095100 total, 55040 used, 2040060 free, 539728 cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
5740 long 20 0 110m 27m 14m S 15.2 1.4 3:13.91 gnome-terminal
4597 root 20 0 95000 31m 4848 S 13.9 1.6 25:29.79 Xorg
5297 long 20 0 246m 70m 19m S 10.3 3.5 14:09.52 compiz
long@long-Ubuntu:~$ mpstat
Linux 3.7.1 (long-Ubuntu) 2013年03月04日 _i686_ (2 CPU)
14时53分16秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
14时53分16秒 all 18.91 4.92 5.15 1.00 0.00 0.04 0.00 0.00 69.99
使用如下命令可以监控单独的CPU使用率信息:long@long-Ubuntu:~$ mpstat -P ALL
Linux 3.7.1 (long-Ubuntu) 2013年03月04日 _i686_ (2 CPU)
14时53分53秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
14时53分53秒 all 18.91 4.91 5.15 0.99 0.00 0.04 0.00 0.00 70.01
14时53分53秒 0 19.02 4.25 5.19 0.66 0.00 0.00 0.00 0.00 70.88
14时53分53秒 1 18.79 5.57 5.10 1.33 0.00 0.07 0.00 0.00 69.13
long@long-Ubuntu:~$ sar -u 2 5
Linux 3.7.1 (long-Ubuntu) 2013年03月04日 _i686_ (2 CPU)
14时54分22秒 CPU %user %nice %system %iowait %steal %idle
14时54分24秒 all 5.51 0.00 1.50 1.00 0.00 91.98
14时54分26秒 all 4.52 0.00 1.26 0.00 0.00 94.22
14时54分28秒 all 4.02 0.00 1.76 0.00 0.00 94.22
14时54分30秒 all 4.77 0.00 1.51 3.77 0.00 89.95
14时54分32秒 all 3.77 0.00 1.51 0.00 0.00 94.72
平均时间: all 4.52 0.00 1.51 0.95 0.00 93.02
long@long-Ubuntu:~$ iostat
Linux 3.7.1 (long-Ubuntu) 2013年03月04日 _i686_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
18.89 4.90 5.18 0.99 0.00 70.04
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 6.75 67.08 58.24 1512659 1313268
工具 |
简单介绍 |
top |
查看进程活动状态以及一些系统状况 |
vmstat |
查看系统状态、硬件和系统信息等 |
iostat |
查看CPU 负载,硬盘状况 |
sar |
综合工具,查看系统状况 |
mpstat |
查看多处理器状况 |
netstat |
查看网络状况 |
iptraf |
实时网络状况监测 |
tcpdump |
抓取网络数据包,详细分析 |
mpstat |
查看多处理器状况 |
tcptrace |
数据包分析工具 |
netperf |
网络带宽工具 |
dstat |
综合工具,综合了 vmstat, iostat, ifstat, netstat 等多个信息 |