jiaming 2010-09-20
Linux平台Cpu使用率的计算
proc文件系统
/proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为内核与进程提供通信的接口。用户和应用程序可以通过/proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取/proc目录中的文件时,proc文件系统是动态从系统内核读出所需信息并提交的。
/proc目录中有一些以数字命名的目录,它们是进程目录。系统中当前运行的每一个进程在/proc下都对应一个以进程号为目录名的目录/proc/pid,它们是读取进程信息的接口。此外,在Linux2.6.0-test6以上的版本中/proc/pid目录中有一个task目录,/proc/pid/task目录中也有一些以该进程所拥有的线程的线程号命名的目录/proc/pid/task/tid,它们是读取线程信息的接口。
/proc/cpuinfo文件
该文件中存放了有关cpu的相关信息(型号,缓存大小等)。
[zhengangen@buick~]$cat/proc/cpuinfo
processor:0
vendor_id:GenuineIntel
cpufamily:15
model:4
modelname:Intel(R)Xeon(TM)CPU3.00GHz
stepping:10
cpuMHz:3001.177
cachesize:2048KB
physicalid:0
siblings:2
coreid:0
cpucores:1
fdiv_bug:no
hlt_bug:no
f00f_bug:no
coma_bug:no
fpu:yes
fpu_exception:yes
cpuidlevel:5
wp:yes
flags:fpuvmedepsetscmsrpaemcecx8apicmtrrpgemcacmovpatpse36clflushdtsacpimmxfxsrssesse2sshttmpbelmpnimonitords_cplcidxtpr
bogomips:6004.52
说明:以下只解释对我们计算Cpu使用率有用的相关参数。
参数解释
processor(0)cpu的一个物理标识
结论1:可以通过该文件根据processor出现的次数统计cpu的逻辑个数(包括多核、超线程)。
/proc/stat文件
该文件包含了所有CPU活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。不同内核版本中该文件的格式可能不大一致,以下通过实例来说明数据该文件中各字段的含义。
实例数据:2.6.24-24版本上的
fjzag@fjzag-desktop:~$cat/proc/stat
cpu38082627275948939081225658189500
cpu022880472168554302871061757666100
cpu115202154107394636201639423400
intr120053222268601105030004730200341942977505019845000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ctxt1434984
btime1252028243
processes8113
procs_running1
procs_blocked0
第一行的数值表示的是CPU总的使用情况,所以我们只要用第一行的数字计算就可以了。下表解析第一行各数值的含义:
参数解析(单位:jiffies)
(jiffies是内核中的一个全局变量,用来记录自系统启动一来产生的节拍数,在linux中,一个节拍大致可理解为操作系统进程调度的最小时间片,不同linux内核可能值有不同,通常在1ms到10ms之间)
user(38082)从系统启动开始累计到当前时刻,处于用户态的运行时间,不包含nice值为负进程。
nice(627)从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间
system(27594)从系统启动开始累计到当前时刻,处于核心态的运行时间
idle(893908)从系统启动开始累计到当前时刻,除IO等待时间以外的其它等待时间iowait(12256)从系统启动开始累计到当前时刻,IO等待时间(since2.5.41)
irq(581)从系统启动开始累计到当前时刻,硬中断时间(since2.6.0-test4)
softirq(895)从系统启动开始累计到当前时刻,软中断时间(since2.6.0-test4)stealstolen(0)whichisthetimespentinotheroperatingsystemswhenrunninginavirtualizedenvironment(since2.6.11)
guest(0)whichisthetimespentrunningavirtualCPUforguestoperatingsystemsunderthecontroloftheLinuxkernel(since2.6.24)
结论2:总的cpu时间totalCpuTime=user+nice+system+idle+iowait+irq+softirq+stealstolen+guest
/proc/<pid>/stat文件
该文件包含了某一进程所有的活动的信息,该文件中的所有值都是从系统启动开始累计
到当前时刻。以下通过实例数据来说明该文件中各字段的含义。
[zhengangen@buick~]#cat/proc/6873/stat
6873(a.out)R6723687367233481968738388608770004195831002503058826541409024564294967295134512640134513720321557904002097798000000017000
说明:以下只解释对我们计算Cpu使用率有用相关参数
参数解释
pid=6873进程号
utime=1587该任务在用户态运行的时间,单位为jiffies
stime=41958该任务在核心态运行的时间,单位为jiffies
cutime=0所有已死线程在用户态运行的时间,单位为jiffies
cstime=0所有已死在核心态运行的时间,单位为jiffies
结论3:进程的总Cpu时间processCpuTime=utime+stime+cutime+cstime,该值包括其所有线程的cpu时间。
/proc/<pid>/task/<tid>/stat文件
该文件包含了某一进程所有的活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。该文件的内容格式以及各字段的含义同/proc/<pid>/stat文件。
注意,该文件中的tid字段表示的不再是进程号,而是linux中的轻量级进程(lwp),即我们通常所说的线程。
结论4:线程Cpu时间threadCpuTime=utime+stime
系统中有关进程cpu使用率的常用命令
ps命令
通过ps命令可以查看系统中相关进程的Cpu使用率的信息。以下在linuxman文档中对ps命令输出中有关cpu使用率的解释:
CPUusageiscurrentlyexpressedasthepercentageoftimespentrunningduringtheentirelifetimeofaprocess.Thisisnotideal,anditdoesnotconformtothestandardsthatpsotherwiseconformsto.CPUusageisunlikelytoadduptoexactly100%.
%cpucpuutilizationoftheprocessin"##.#"format.ItistheCPUtimeuseddividedbythetimetheprocesshasbeenrunning(cputime/realtimeratio),expressedasapercentage.Itwillnotaddupto100%unlessyouarelucky.
结论5:ps命令算出来的cpu使用率相对于进程启动时的平均值,随着进程运行时间的增大,该值会趋向于平缓。
top命令
通过top命令可以查看系统中相关进程的实时信息(cpu使用率等)。以下是man文档中对top命令输出中有关进程cpu使用率的解释。
#C--LastusedCPU(SMP)Anumberrepresentingthelastusedprocessor.InatrueSMPenvironmentthiswilllikelychangefrequentlysincethekernelintentionallyusesweakaffinity.Also,theveryactofrunningtopmaybreakthisweakaffinityandcausemoreprocessestochangeCPUsmoreoften(becauseoftheextrademandforcputime).
%CPU--CPUusageThetask’sshareoftheelapsedCPUtimesincethelastscreenupdate,expressedasapercent-ageoftotalCPUtime.InatrueSMPenvironment,ifIrixmodeisOff,topwilloperateinSolarismodewhereatask’scpuusagewillbedividedbythetotalnumberofCPUs.
结论6:某一个线程在其运行期间其所使用的cpu可能会发生变化。
结论7:在多核的情况下top命令输出的cpu使用率实质是按cpu个数*100%计算的。
单核情况下Cpu使用率的计算
基本思想
通过读取/proc/stat、/proc/<pid>/stat、/proc/<pid>/task/<tid>/stat以及/proc/cpuinfo这几个文件获取总的Cpu时间、进程的Cpu时间、线程的Cpu时间以及Cpu的个数的信息,然后通过一定的算法进行计算(采样两个足够短的时间间隔的Cpu快照与进程快照来计算进程的Cpu使用率)。
总的Cpu使用率计算
计算方法:
1、采样两个足够短的时间间隔的Cpu快照,分别记作t1,t2,其中t1、t2的结构均为:
(user、nice、system、idle、iowait、irq、softirq、stealstolen、guest)的9元组;
2、计算总的Cpu时间片totalCpuTime
a)把第一次的所有cpu使用情况求和,得到s1;
b)把第二次的所有cpu使用情况求和,得到s2;
c)s2-s1得到这个时间间隔内的所有时间片,即totalCpuTime=j2-j1;
3、计算空闲时间idle
idle对应第四列的数据,用第二次的第四列-第一次的第四列即可
idle=第二次的第四列-第一次的第四列
6、计算cpu使用率
pcpu=100*(total-idle)/total
某一进程Cpu使用率的计算
计算方法:
1.采样两个足够短的时间间隔的cpu快照与进程快照,
a)每一个cpu快照均为(user、nice、system、idle、iowait、irq、softirq、stealstolen、guest)的9元组;
b)每一个进程快照均为(utime、stime、cutime、cstime)的4元组;
2.分别根据结论2、结论3计算出两个时刻的总的cpu时间与进程的cpu时间,分别记作:totalCpuTime1、totalCpuTime2、processCpuTime1、processCpuTime2
3.计算该进程的cpu使用率pcpu=100*(processCpuTime2–processCpuTime1)/(totalCpuTime2–totalCpuTime1)(按100%计算,如果是多核情况下还需乘以cpu的个数);
实验数据
实验一:监控一空循环的进程的cpu使用率。
说明:左边的数据是按以上算法得到的数据,其中采样的时间间隔与top命令刷新屏幕的时间间隔相同。
按以上方法计算得到的cpu使用率
通过top命令得到的
99.50083
98.333336
98.0
98.83138
99.0
99.0
99.83361
98.83527
98.4975
PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
7639fjzag200206m10m7136S992.21:00.74java
7639fjzag200206m10m7136S992.21:03.71java
7639fjzag200206m10m7136S992.21:06.67java
7639fjzag200206m10m7136S992.21:09.63java
7639fjzag200206m10m7136S982.21:12.59java
7639fjzag200206m10m7136S992.21:15.55java
7639fjzag200206m10m7136S1002.21:18.55java
7639fjzag200206m10m7136S1002.21:21.54java
7639fjzag200206m10m7136S992.21:24.52java
7639fjzag200206m10m7136S982.21:27.46java
实验二:监控jconsole进程的cpu使用率。
说明:左边的数据是按以上算法得到的数据,其中采样的时间间隔与top命令刷新屏幕的时间间隔相同。
按以上方法计算得到的cpu使用率
通过top命令得到的
8.681135
12.0
10.350584
7.6539097
7.6539097
5.0
13.021703
11.0
8.666667
PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
7753fjzag200252m72m22mS1014.40:18.70jconsole
7753fjzag200252m72m22mS1214.40:19.07jconsole
7753fjzag200252m72m22mS1114.40:19.39jconsole
7753fjzag200252m72m22mS714.40:19.61jconsole
7753fjzag200252m72m22mS714.40:19.83jconsole
7753fjzag200252m72m22mS514.40:19.97jconsole
7753fjzag200252m72m22mS1414.40:20.38jconsole
7753fjzag200252m72m22mS1014.40:20.68jconsole
7753fjzag200252m72m22mS914.50:20.96jconsole
某一线程Cpu使用率的计算
计算方法:
1.采样两个足够短的时间隔的cpu快照与线程快照,
a)每一个cpu快照均为(user、nice、system、idle、iowait、irq、softirq、stealstealon、guest)的9元组;
b)每一个线程快照均为(utime、stime)的2元组;
2.分别根据结论2、结论4计算出两个时刻的总的cpu时间与线程的cpu时间,分别记作:totalCpuTime1、totalCpuTime2、threadCpuTime1、threadCpuTime2
3.计算该线程的cpu使用率pcpu=100*(threadCpuTime2–threadCpuTime1)/(totalCpuTime2–totalCpuTime1)(按100%计算,如果是多核情况下还需乘以cpu的个数);
实验数据
实验一:监控一空循环的线程的cpu使用率。
说明:左边的数据是按以上算法得到的数据,其中采样的时间间隔与top命令刷新屏幕的时间间隔相同。
按以上方法计算得到的cpu使用率
通过top命令得到的
98.83138
97.00997
96.98997
97.49583
98.169716
96.8386
97.333336
93.82304
98.66667
PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
7649fjzag200206m10m7136R972.27:22.94java
7649fjzag200206m10m7136R972.27:25.86java
7649fjzag200206m10m7136R972.27:28.76java
7649fjzag200206m10m7136R992.27:31.72java
7649fjzag200206m10m7136R982.27:34.65java
7649fjzag200206m10m7136R962.27:37.53java
7649fjzag200206m10m7136R982.27:40.47java
7649fjzag200206m10m7136R962.27:43.34java
7649fjzag200206m10m7136R972.27:46.25java
实验二:监控jconsole程序某一线程的cpu使用率。
说明:左边的数据是按以上算法得到的数据,其中采样的时间间隔与top命令刷新屏幕的时间间隔相同。
按以上方法计算得到的cpu使用率
通过top命令得到的
1.3400335
6.644518
1.3333334
0.6677796
0.6666667
1.3333334
1.3333334
PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
7755fjzag200251m72m22mS114.40:11.92jconsole
7755fjzag200251m72m22mS714.40:12.12jconsole
7755fjzag200251m72m22mS214.40:12.18jconsole
7755fjzag200251m72m22mS014.40:12.18jconsole
7755fjzag200251m72m22mS114.40:12.20jconsole
7755fjzag200251m72m22mS114.40:12.24jconsole
7755fjzag200251m72m22mS114.40:12.28jconsole
多核情况下cpu使用率的计算
以下通过实验数据来说明多核情况下某一进程cpu使用率是按cpu个数*100%计算的.
实验一
描述:
在双核的情况下作的一组实验,第一组数据是通过ps-eLopid,lwp,pcpu|grep9140命令查看进程号为9140的进程中各线程的详细信息。第二组数据是通过ps命令查看进程号为9140进程的cpu使用率。
数据一:
pidlwp%cpu
914091400.0
914091410.0
914091420.0
914091430.0
914091440.0
914091490.0
914091500.0
914091510.0
914091520.1
9140915396.6该线程是一个空循环
9140915495.9该线程是一个空循环
以上除了红色标注出来的两个线程以外,其他的线程都是后台线程。
数据二:
pid%cpu
9140193
实验二
描述:
在单核的情况下作的一组实验,第一组数据是通过ps-eLopid,lwp,pcpu|grep6137命令查看进程号为6137的进程中各线程的详细信息。第二组数据是通过ps命令查看进程号为6137进程的cpu使用率。
数据一:
pidlwp%cpu
613761370.0
613761380.1
613761430.0
613761440.0
613761450.0
613761460.0
613761470.0
613761480.0
613761490.0
6137615046.9空循环线程
6137615146.9空循环线程
以上除了红色标注出来的两个线程以外,其他的线程都是后台线程。
数据二
pid%cpu
613792.9
主要问题:
1.不同内核版本/proc/stat文件格式不大一致。/proc/stat文件中第一行为总的cpu使用情况。
各个版本都有的4个字段:user、nice、system、idle
2.5.41版本新增字段:iowait
2.6.0-test4新增字段:irq、softirq
2.6.11新增字段:stealstolen:whichisthetimespentinotheroperating
systemswhenrunninginavirtualizedenvironment
2.6.24新增字段:guest:whichisthetimespentrunningavirtualCPUforguestoperatingsystemsunderthecontroloftheLinuxkernel
2./proc/pid/task目录是Linux2.6.0-test6之后才有的功能。
3.关于出现cpu使用率为负的情况,目前想到的解决方案是如果出现负值,连续采样计算cpu使用率直到为非负。
4.有些线程生命周期较短,可能在我们采样期间就已经死掉了.