部分 从灾难中
本来我想写一个小程序来测试CPU其他工具利用它可以检验类数据的性能。以后参考IPbench中间cpu_target_lukem插件实现我们的功能。原理非常简单:就是我们给程序设置了极低的优先级,假设有不论什么计算任务都会打断它,而假设没有计算任务,我们的程序就会占用cpu时间,所以我们的程序的执行时间基本上能够算作CPU的闲暇时间。
所以我们计算总的CPU利用率的方法就是 : CPU利用率 = 1 - 程序占用cpu时间/程序总的执行时间。
主要功能实现代码例如以下:
- x0 = get_cycles();
-
- while (calc) {
- x1 = x0;
- x0 = get_cycles();
-
- delta = x0 - x1;
- total += delta;
-
-
- if (delta < PROFILE_CONTEXT_COST)
- idle += delta;
-
- timer_buffer.idle = idle;
- timer_buffer.total = total;
- }
从而本程序中的CPU利用率 = (1- timer_buffer.idle/timer_buffer.total)*100 %,
之后我们编译执行本程序。程序输出为:
[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表示登陆port。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利用率的呢?
第二节 CPU利用率和CPU负载
在Linux/Unix下,CPU利用率(CPU utilization)分为用户态,系统态和空暇态,分别表示CPU处于用户态运行的时间,系统内核运行的时间,和空暇系统进程运行的时间。平时所说的CPU利用率是指:CPU运行非系统空暇进程的时间 / CPU总的运行时间。(上述代码中使用的方法为:1
- CPU空暇执行时间/总执行时间 ,与这个计算方法原理上是一样的)
在Linux的内核中,有一个全局变量:Jiffies。 Jiffies代表时间。它的单位随硬件平台的不同而不同,系统里定义了一个常数HZ----代表每秒种最小时间间隔的数目。这样jiffies的单位就是1/HZ。Intel平台jiffies的单位是1/100秒,这就是系统所能分辨的最小时间间隔了。
每一个CPU时间片,Jiffies都要加1。
CPU的利用率就是用运行用户态+系统态的Jiffies除以总的Jifffies来表示。
那么。另一个常常easy与CPU利用率(CPU
utilization)混淆的词 -- CPU负载(CPU load)。CPU负载取决于CPU队列长度而不是CPU利用率,由于一个主机负载过重时。它的CPU利用率会接近100%,从而无法准确反应负载状况,而使用CPU队列长度则能够非常直接反应CPU的负载量。比方说两个系统,当中一个系统有3个进程在队列中。而还有一台有6个进程在队列,假设使用CPU利用率表示负载水平,他们可能都是接近100%,而使用CPU队列长度他们的负载量全然不同。
我们怎样理解CPU负载?一仅仅单核的处理器能够形象得比喻成一条单车道。那么:
*** 0.00 表示眼下桥面上没有不论什么的车流。 实际上这样的情况与 0.00 和 1.00
之间是同样的,总而言之非常通畅,过往的车辆能够丝毫不用等待的通过。
*** 1.00 表示刚好是在这座桥的承受范围内。 这样的情况不算糟糕。仅仅是车流会有些堵,只是这样的情况可能会造成交通越来越慢。
*** 超过 1.00。那么说明这座桥已经超出负荷。交通严重的拥堵。 那么情况有多糟糕? 比如 2.00 的情况说明车流已经超出了桥所能承受的一倍。那么将有多余过桥一倍的车辆正在焦急的等待。
3.00 的话情况就更不妙了。说明这座桥基本上已经快承受不了。还有超出桥负载两倍多的车辆正在等待。
上面的情况和处理器的负载情况很相似。一辆汽车的过桥时间就好比是处理器处理某线程 的实际时间。Unix
系统定义的进程执行时长为全部处理器内核的处理时间加上线程 在队列中等待的时间。
和收过桥费的管理员一样。你当然希望你的汽车(操作)不会被焦急的等待。所以,理想状态 下。都希望负载平均值小于 1.00 。当然不排除部分峰值会超过 1.00,但长此以往保持这 个状态,就说明会有问题,这时候你应该会非常焦急。
在多处理器系统中,负载均值是基于内核的数量决定的。以
100% 负载计算,1.00 表示单个处理器,而 2.00 则说明有两个双处理器,那么 4.00 就说明主机具有四个处理器。回到我们上面有关车辆过桥的比喻。
1.00 我说过是「一条单车道的道路」。
那么在单车道 1.00 情况中。说明这桥梁已经被车塞满了。而在双处理器系统中,这意味着多出了一倍的 负载,也就是说还有 50% 的剩余系统资源 ---- 由于还有另外条车道能够通行。
所以,单处理器已经在负载的情况下,双处理器的负载满额的情况是 2.00,它另一倍的资源能够利用。
实际上Linux系统中非常多都是用CPU负载均值(load average)来代表当前系统的负载状况,比方使用top命令:
- 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”
使用“uptime”命令,效果也是类似:
- long@long-Ubuntu:~$ uptime
- 20:15:01 up 3:07, 6 users, load average: 0.43, 0.97, 1.05
这三个数各自是:一分钟内、五分钟内、十五分钟内的系统负载均值。也就是说,从右向左看这几个数据,我们能够推断系统负载的发展趋势。
其实。这正是CPU负载所须要測量的,由于负载均值不包含那些等待I/O、网络、数据或者其它不依赖CPU的进程或线程,它关注的不过积极要求CPU时间的进程或线程。这与CPU利用率是有非常大不同的。
负载均值与CPU利用率在两个方面有非常大的差别:
1) 负载均值用来估量CPU利用率的发展趋势,而不是某一时刻的状况
2) 负载均值包含全部CPU的需求,而不不过在測量时活跃的
第三节 怎样计算CPU利用率
在Linux系统中。能够用/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)/(total_2
- total_1)*100
cpu usage=[(user_2 +sys_2+nice_2) - (user_1 + sys_1+nice_1)]/(total_2 - total_1)*100
第四节 对第一节中的puzzle进行解释
再回想一下三个疑问:第一、为毛执行a.out和b.out显示的CPU利用率不一样……第二、为毛在ps中显示的a.out和b.out的CPU利用率不一样?第三、为毛ps中a.out和b.out的CPU利用率分别为94.1%和90.0%,而两者加一起远远大于100%?!!
实际上,这些问题感觉非常诡异。可是经过我一番学习之后。发现,答案事实上非常easy。
首先,为啥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
第五节 Linux提供的一些查看系统信息的工具
使用以下这些命令我们能够查询总的CPU使用率、单独的CPU使用率(对于对称多处理机器SMP)、从你上次启动后的平均CPU使用率等。
4.1 老当益壮的top命令
使用top命令能够动态的查看CPU使用率。它会显示当前内核管理着的任务信息。它还会显示上线时间、负载均值、物理和交换内存使用状况。使用例如以下:
- 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
4.2 使用"mpstat"命令
使用这个命令,你须要先安装sysstat工具。对于Debian或Ubuntu用户,能够通过apt-get直接安装:
$ apt-get install sysstat
使用例如以下命令查看CPU使用率信息:
$ mpstat
- 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使用率信息:
$ mpstat -P ALL
- 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
4.3 使用"sar"命令
使用sar命令显示CPU使用率的语法例如以下:
$ sar -u 2 5 ( sar [ 选项 ] [ <时间间隔> [ <次数> ] ])
这条命令会显示2秒内的CPU使用率,总共显示5次。
- 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
4.4 使用"iostat"命令
"iostat"命令能够用来查询从系统启动以来的是CPU平均使用率以及设备或者分区的I/O状况:
$ iostat
- 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
4.5 GUI Tools 一些有图形界面的工具
KDE桌面环境有一些系统监控器一类的工具能够用来监控CPU使用率甚至很多其它的系统信息(比方说CPU负载状况、物理内存以及交换分区的数据占用信息)。你还能够使用它来杀死一些进程。
下表总结了若干Linux下的工具:
工具
|
简介
|
top
|
查看进程活动状态以及一些系统状况
|
vmstat
|
查看系统状态、硬件和系统信息等
|
iostat
|
查看CPU 负载。硬盘状况
|
sar
|
综合工具。查看系统状况
|
mpstat
|
查看多处理器状况
|
netstat
|
查看网络状况
|
iptraf
|
实时网络状况监測
|
tcpdump
|
抓取网络数据包,具体分析
|
mpstat
|
查看多处理器状况
|
tcptrace
|
数据包分析工具
|
netperf
|
网络带宽工具
|
dstat
|
综合工具,综合了 vmstat, iostat, ifstat, netstat 等多个信息 |
版权声明:本文博客原创文章,博客,未经同意,不得转载。