Solaris Load Averages calculate techique
在solaris系统中有一个uptime 命令,可以查看cpu 的平均负荷。如下:
# uptime
4:23pmup 119 day(s), 22:05,2 users,load average: 0.07, 0.06, 0.05
其中的0.07,0.06,0.05分别是5,10,15分钟的统计平均值。
我们先来看看源代码中,统计平均值得到的函数调用关系图:
http://blog.chinaunix.net/photo/60942_080204172553.png
图中的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 = { 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 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; i3; 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-nrun)/6;
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/60942/showart_476260.html
页:
[1]