Linux下的CPU利用率计算原理

来源:互联网 发布:什么是软件原型 编辑:程序博客网 时间:2024/05/16 17:14

我们在搞性能测试的时候,对后台服务器的CPU利用率监控是一个常用的手段。服务器的CPU利用率高,则表明服务器很繁忙。如果前台响应时间越来越大,而后台CPU利用率始终上不去,说明在某个地方有瓶颈了,系统需要调优。这个是即使不懂技术的人都容易理解的事情。

上面理解对吗?我个人觉得不十分准确。这个要看后台你测试的进程是什么类型的。如果是计算密集型的进程,当前端压力越来越大的时候,很容易把CPU利用率打上去。但是如果是I/O网络密集型的进程,即使客户端的请求越来越多,但是服务器CPU不一定能上去,这个是你要测试的进程的自然属性决定的。比较常见的就是,大文件频繁读写的cpu开销远小于小文件频繁读写的开销。因为在I/O吞吐量一定时,小文件的读写更加频繁,需要更多的cpu来处理I/O的中断。

在Linux/Unix下,CPU利用率分为用户态系统态空闲态,分别表示CPU处于用户态执行的时间,系统内核执行的时间,和空闲系统进程执行的时间。平时所说的CPU利用率是指:CPU执行非系统空闲进程的时间 / CPU总的执行时间

在Linux的内核中,有一个全局变量:Jiffies。 Jiffies代表时间。它的单位随硬件平台的不同而不同。系统里定义了一个常数HZ,代表每秒种最小时间间隔的数目。这样jiffies的单位就是1/HZ。Intel平台jiffies的单位是1/100秒,这就是系统所能分辨的最小时间间隔了。每个CPU时间片,Jiffies都要加1。CPU的利用率就是用执行用户态+系统态的Jiffies除以总的Jifffies来表示。

在Linux系统中,可以用/proc/stat文件来计算cpu的利用率。这个文件包含了所有CPU活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。如:

  1. [sailorhzr@builder ~]$ cat /proc/stat  cpu  432661 13295   86656 422145968   171474 233   5346  cpu 0 123075   2462 23494   105543694 16586   0 4615  cpu 1 111917   4124 23858   105503820 69697   123 371  cpu 2 103164   3554 21530   105521167 64032   106 334  cpu 3 94504   3153 17772   105577285 21158   4 24  intr  1065711094 1057275779   92 0   6 6   0 4   0 3527   0 0   0 70   0 20   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   7376958 0   0 0   0 0   0 0   1054602 0   0 0   0 0   0 0   30 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0   0 0  ctxt  19067887  btime  1139187531  processes  270014  procs_running  1  procs_blocked  0     
    输出解释

CPU 以及CPU0、CPU1、CPU2、CPU3每行的每个参数意思(以第一行为例)为:

参数解释
user (432661)

 


nice (13295)

 


system (86656)
 
 


idle (422145968)



iowait (171474)

 

irq (233)

 
softirq (5346) 
 
从系统启动开始累计到当前时刻,用户态的CPU时间(单位:jiffies) ,不包含 nice值为负进程。1jiffies=0.01秒


从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间(单位:jiffies)



从系统启动开始累计到当前时刻,核心时间(单位:jiffies)
 


从系统启动开始累计到当前时刻,除硬盘IO等待时间以外其它等待时间(单位:jiffies)


从系统启动开始累计到当前时刻,硬盘IO等待时间(单位:jiffies) ,

从系统启动开始累计到当前时刻,硬中断时间(单位:jiffies)
 
从系统启动开始累计到当前时刻,软中断时间(单位:jiffies) 

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

“intr”这行给出中断的信息,第一个为自系统启动以来,发生的所有的中断的次数;然后每个数对应一个特定的中断自系统启动以来所发生的次数。

“ctxt”给出了自系统启动以来CPU发生的上下文交换的次数。

“btime”给出了从系统启动到现在为止的时间,单位为秒。

“processes (total_forks) 自系统启动以来所创建的任务的个数目。

“procs_running”:当前运行队列的任务的数目。

“procs_blocked”:当前被阻塞的任务的数目。

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

  1. cpu usage=(idle2-idle1)/(cpu2-cpu1)*100 
  2. cpu usage=[(user_2 +sys_2+nice_2) - (user_1 + sys_1+nice_1)]/(total_2 - total_1)*100 
  3.  

以下用分别用bash和perl做的一个cpu利用率的计算:

本人注:以下代码则采用公式为:

  1. total_0USER[0]+NICE[0]+SYSTEM[0]+IDLE[0]+IOWAIT[0]+IRQ[0]+SOFTIRQ[0]  
  2. total_1=USER[1]+NICE[1]+SYSTEM[1]+IDLE[1]+IOWAIT[1]+IRQ[1]+SOFTIRQ[1]  
  3. cpu usage=(IDLE[0]-IDLE[1]) / (total_0-total_1) * 100 
  4.  

###bash 代码

  1. CODE:#!/bin/sh  
  2.  
  3. ##echo user nice system idle iowait irq softirq  
  4. CPULOG_1=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')  
  5. SYS_IDLE_1=$(echo $CPULOG_1 | awk '{print $4}')  
  6. Total_1=$(echo $CPULOG_1 | awk '{print $1+$2+$3+$4+$5+$6+$7}')  
  7.  
  8. sleep 5  
  9.  
  10. CPULOG_2=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')  
  11. SYS_IDLE_2=$(echo $CPULOG_2 | awk '{print $4}')  
  12. Total_2=$(echo $CPULOG_2 | awk '{print $1+$2+$3+$4+$5+$6+$7}')  
  13.  
  14. SYS_IDLE=`expr $SYS_IDLE_2 - $SYS_IDLE_1`  
  15.  
  16. Total=`expr $Total_2 - $Total_1`  
  17. SYS_USAGE=`expr $SYS_IDLE/$Total*100 |bc -l`  
  18.  
  19. SYS_Rate=`expr 100-$SYS_USAGE |bc -l`  
  20.  
  21. Disp_SYS_Rate=`expr "scale=3; $SYS_Rate/1" |bc`  
  22. echo $Disp_SYS_Rate%  
  23.  
  24.    

###perl 代码

  1. #!/usr/bin/perl  
  2. use warnings;  
  3. $SLEEPTIME=5;  
  4. if (-e "/tmp/stat") {  
  5. unlink "/tmp/stat";  
  6. }  
  7. open (JIFF_TMP, ">>/tmp/stat") || die "Can't open /proc/stat file!\n";  
  8. open (JIFF, "/proc/stat") || die "Can't open /proc/stat file!\n";  
  9. @jiff_0=<JIFF>;  
  10. print JIFF_TMP $jiff_0[0] ;  
  11. close (JIFF);  
  12. sleep $SLEEPTIME;  
  13. open (JIFF, "/proc/stat") || die "Can't open /proc/stat file!\n";  
  14. @jiff_1=<JIFF>;  
  15. print JIFF_TMP $jiff_1[0];  
  16. close (JIFF);  
  17. close (JIFF_TMP);  
  18. @USER=`awk '{print \$2}' "/tmp/stat"`;  
  19. @NICE=`awk '{print \$3}' "/tmp/stat"`;  
  20. @SYSTEM=`awk '{print \$4}' "/tmp/stat"`;  
  21. @IDLE=`awk '{print \$5}' "/tmp/stat"`;  
  22. @IOWAIT=`awk '{print \$6}' "/tmp/stat"`;  
  23. @IRQ=`awk '{print \$7}' "/tmp/stat"`;  
  24. @SOFTIRQ=`awk '{print \$8}' "/tmp/stat"`;  
  25. $JIFF_0=$USER[0]+$NICE[0]+$SYSTEM[0]+$IDLE[0]+$IOWAIT[0]+$IRQ[0]+$SOFTIRQ[0];  
  26. $JIFF_1=$USER[1]+$NICE[1]+$SYSTEM[1]+$IDLE[1]+$IOWAIT[1]+$IRQ[1]+$SOFTIRQ[1];  
  27. $SYS_IDLE=($IDLE[0]-$IDLE[1]) / ($JIFF_0-$JIFF_1) * 100;  
  28. $SYS_USAGE=100 - $SYS_IDLE;  
  29. printf ("The CPU usage is %1.2f%%\n",$SYS_USAGE);

/proc/stat explained Various pieces of information about kernel activity are available in the/proc/stat file.All of the numbers reported in this file are aggregates since the system first booted.For a quick look, simply cat the file:> cat /proc/statcpu  2255 34 2290 22625563 6290 127 456cpu0 1132 34 1441 11311718 3675 127 438cpu1 1123 0 849 11313845 2614 0 18intr 114930548 113199788 3 0 5 263 0 4 [... lots more numbers ...]ctxt 1990473btime 1062191376processes 2915procs_running 1procs_blocked 0The very first "cpu" line aggregates the numbers in all of the other "cpuN" lines.These numbers identify the amount of time the CPU has spent performing different kinds of work. Time units are in USER_HZ or Jiffies (typically hundredths of a second).
The meanings of the columns are as follows, from left to right :user : normal processes executing in user modenice : niced processes executing in user modesystem : processes executing in kernel modeidle : twiddling thumbsiowait : waiting for I / O to completeirq : servicing interruptssoftirq : servicing softirqs
The "intr" line gives counts of interrupts serviced since boot time, for eachof the possible system interrupts. The first column is the total of all interrupts serviced; each subsequent column is the total for that particular interrupt.The "ctxt" line gives the total number of context switches across all CPUs.The "btime" line gives the time at which the system booted, in seconds sincethe Unix epoch.The "processes" line gives the number of processes and threads created, which includes (but is not limited to) those created by calls to the fork() and clone() system calls.The "procs_running" line gives the number of processes currently running on CPUs.The "procs_blocked" line gives the number of processes currently blocked, waiting for I/O to complete.copied from the kernel documentation of the /proc filesystem

原创粉丝点击