- 论坛徽章:
- 0
|
在solaris 系统中有一个uptime 命令,可以查看cpu 的平均负荷。如下:
# uptime
4:23pm up 119 day(s), 22:05, 2 users, load average: 0.07, 0.06, 0.05
其中的0.07,0.06,0.05分别是5,10,15分钟的统计平均值。
我们先来看看源代码中,统计平均值得到的函数调用关系图:
![]()
图中的clock函数会每秒被调用一次,clock执行的操作如下:
1.首先调用loadavg_update函数从cpu_t::cpu_acct[]中读出当前采样的cpu值。这个值存储在struct loadavg_s中,这个结构存储10个的采样数据,也就是10sec的值。该结构存储10sec数据是循环冲写的。
2.genloadavg函数计算10秒的,平静cpu值。
3.calcloadavg根据genloadavg计算的10sec平静值,计算5,10,15分钟的平静值,存储在avenrun全局数据中。
根据10秒平静值,计算5,10,15分钟的平静值的算法很有意思,搞的很复杂,代码如下:
static void
calcloadavg(int nrun, uint64_t *hp_ave)
{
static int64_t f[3] = { 135, 27, 9 };
uint_t i;
int64_t q, r;
/*
* Compute load average over the last 1, 5, and 15 minutes
* (60, 300, and 900 seconds). The constants in f[3] are for
* exponential decay:
* (1 - exp(-1/60)) 13 = 135,
* (1 - exp(-1/300)) 13 = 27,
* (1 - exp(-1/900)) 13 = 9.
*/
/*
* a little hoop-jumping to avoid integer overflow
*/
for (i = 0; i 3; i++) {
q = (hp_ave >> 16) 7;
r = (hp_ave & 0xffff) 7;
hp_ave += ((nrun - q) * f - ((r * f) >> 16)) >> 4;
}
}
上面的算法还没有看懂,也不知道sun公司的人为什么搞这么复杂。个人认为,直接存储前10秒的平均值,一个线性计算就可以很简单算出了。比如,前10秒和当前10秒平静值分别存储在nrun【2】中,计算1分钟的平均值用如下方法不久可以了,hp_ave +=(nrun[1]-nrun[0])/6;
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/60942/showart_476260.html |
|