第一节 祸起
本来就是想通过写个小程序测试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;
- }
从而本程序中的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表示登陆端口;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利用率的呢?