Sheppard Y

keep thinking keep coding.

top里显示的cpu百分比计算方式

2016-07-11 日更新
此篇博客已经迁移到新博客,并做行文检查和优化排版:
http://blog.clawz.me/2013/11/07/13-top-source/


 top看到的cpu信息解释的不是很清晰,就看下源码怎么写的吧。
        程序很简单,基本都在top.c里。
        load里的cpu详细信息代码如下:
 1 smpcpu = cpus_refresh(smpcpu);
 2 
 3 if (CHKw(Curwin, View_CPUSUM)) {
 4         // display just the 1st /proc/stat line
 5         summaryhlp(&smpcpu[Cpu_tot], "Cpu(s):");
 6 else {
 7         int i;
 8         char tmp[SMLBUFSIZ];
 9         // display each cpu's states separately
10         for (i = 0; i < Cpu_tot; i++) {
11                 snprintf(tmp, sizeof(tmp), "Cpu%-3d:", smpcpu[i].id);
12                 summaryhlp(&smpcpu[i], tmp);
13         }
14 }
        
        Cpu_tot为cpu数量。
        cpus_refresh函数里从/proc/stat文件里读入cpu信息,然后装入smpcpu里。smpcpu为大小为Cpu_tot+1个CPU_t成员的数组。
        /proc/stat文件的头几行为:
cpu %%
cpu0 
%%
cpu1 
%%
        第一行的cpu信息装入smpcpu[Cpu_tot],之后的cpu0\cpu1\...装入smpcpu[0]\smpcpu[1\...。
        View_CPUSUM这个由1键来控制的那个开关,开关关闭时只显示smpcpu的Cpu_tot,开关开启时显示的是smpcpu的下标0~Cpu_tot-1的成员。即,top的默认在开头显示的cpu详细信息显示的是/proc/stat的第一行处理后,按下1键,显示的时/proc/stat后续各cpu数据。
        /proc/stat里都是数字,下边看看top里显示的百分比怎么算的。
        CPU_t的定义:
 1 // These typedefs attempt to ensure consistent 'ticks' handling
 2 typedef unsigned long long TIC_t;
 3 typedef          long long SIC_t;
 4 
 5 // This structure stores a frame's cpu tics used in history
 6 // calculations.  It exists primarily for SMP support but serves
 7 // all environments.
 8 typedef struct CPU_t {
 9         TIC_t u, n, s, i, w, x, y, z; // as represented in /proc/stat
10         TIC_t u_sav, s_sav, n_sav, i_sav, w_sav, x_sav, y_sav, z_sav; // in the order of our display
11         unsigned id;  // the CPU ID number
12 } CPU_t;
        每次从/proc/stat取的数据称为一帧的数据,会从到CPU_t结构体的第一行成员里,上次的数据即上一帧的数据就拷到CPU_t的第二排带_sav后缀的成员里,一一对应。
        summaryhlp函数里计算我们想看的cpu各详细指标的百分比。只取部分代码或伪码做演示:
 1 SIC_t u_frme, s_frme, n_frme, i_frme, w_frme, x_frme, y_frme, z_frme, tot_frme, tz;
 2 float scale;
 3 u_frme = cpu->- cpu->u_sav;
 4 s_frme = cpu->- cpu->s_sav;
 5 
 6 tot_frme = u_frme + s_frme + n_frme + i_frme + w_frme + x_frme + y_frme + z_frme;
 7 if (tot_frme < 1) tot_frme = 1;
 8 scale = 100.0 / (float)tot_frme;
 9 
10 us% = (float)u_frme * scale;
11 sy% = (float)s_frme * scale;
12 
13 cpu->u_sav = cpu->u;
14 cpu->s_sav = cpu->s;
15 
        每个进程占cpu百分比计算:
1 Frame_tscale = 100.0f / ((float)Hertz * (float)et * (Rc.mode_irixps ? 1 : Cpu_tot));
2 float u = (float)p->pcpu * Frame_tscale;
        算的是两帧之间总时间片数量,各进程占的时间片数量百分比。

posted on 2013-11-07 19:20 Sheppard Y 阅读(1595) 评论(1)  编辑 收藏 引用 所属分类: 开源

评论

# re: top里显示的cpu百分比计算方式 2014-12-11 15:50 idoplay

楼主好,我最近也在看top源代码,有好多不懂得地方想请教一下。
就是每个进程占用的CPU百分比的计算方法这里,
Frame_tscale = 100.0f / ((float)Hertz * (float)et * (Rc.mode_irixps ? 1 : Cpu_tot));
这个的意思指的是CPU数量?Rc.mode_irixps ? 1 : Cpu_tot,为什么是1 呢?
float u = (float)p->pcpu * Frame_tscale; 这句的意思是指进程占用的单个CPU的百分比吗。这句后面是if (u > pcpu_max_value) u = pcpu_max_value; 我看pcpu_max_value被定义为99.9,意思是说,进程的cpu占用率超过99.9的时候,就让它的占用率为99.9 ,难道进程的CPU占用率不能为100%吗,并且什么情况会超过100%呢?

(float)p->pcpu 这个值是怎么计算出来的?是通过这个函数吗procs_refresh。跟到这里找到readproc,又跟到proc_t*(*reader)(struct PROCTAB *restrict const, proc_t *restrict const);就找不到了。  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2013年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

留言簿(1)

随笔分类(77)

随笔档案(58)

me

基友

同行

业界前辈

最新随笔

搜索

积分与排名

最新评论

阅读排行榜