使用top命令时,我们会看到第一行有个
1 |
load average: 0.01, 0.01, 0.00 |
当然,别的命令也看的到,比如uptime,w。
使用strace追踪uptime很容易发现这三个数据来自/proc/loadavg文件。另几个命令也是通过读取这个文件得到的。
1 |
$ strace -eopen uptime |
2 |
#省略掉无关内容 |
3 |
open ( "/proc/loadavg" , O_RDONLY) = 4 |
load average是什么:
三个数字分别显示系统在1分钟,5分钟,15分钟之内的load情况。
load表示cpu就绪队列中任务的数量,也就是等待cpu的进程数。当然,三个值是取得平均值,还有平滑处理。为什么强调是就绪队列,因为这里的进程等待的就是cpu,这可以看出cpu的压力。
通常情况,这个值应该在cpu核数的2倍以内。
可以通过以下命令查看cpu核心数。
1 |
grep 'model name' /proc/cpuinfo | wc -l |
load average如何得到:
三个数字是由内核计算出的。如果光是得出就绪队列长度,内核中必然有个现成的值。但是这三个值是平均值,平均则需要采样再计算。每隔5秒计算一次平均负载值。
前面说过,这个不是单纯的平均,还使用了平滑处理。
Exponential Smoothing方程:
公式源自Exponential Smoothing方程。Y(t)= Y(t-1) + a*[X(t) – Y(t-1)];
X(t)是原始数据,即就绪队列长度,a是一个用于平滑的值。在这里a用1-e^(-5/p)代入,p对应60,300,900。(就是三个时间间隔)
1 |
load1 = load1 * exp (-5 / 60) + n * (1 – exp (-5 / 60 )) |
2 |
load5 = load5 * exp (-5 / 300) + n * (1 – exp (-5 / 300)) |
3 |
load15 = load15 * exp (-5 / 900) + n * (1 – exp (-5 / 900)) |
4 |
//exp表示e的指数。n代表的是active_tasks,即当前就绪队列长度。 |
5 |
//当然,真的代码里这几个exp的值都是预先计算好了的。 |
6 |
#define EXP_1 1884 /* 1/exp(5sec/1min) */ |
7 |
#define EXP_5 2014 /* 1/exp(5sec/5min) */ |
8 |
#define EXP_15 2037 /* 1/exp(5sec/15min) */ |
可以看出,移动平均间隔越大,值对移动平均的影响趋向减小。局部的load抖动不会对load average造成重大影响,使其平滑。
fixed-point arithmetic(定点算数):
因为Linux内禁止浮点运算,因此系统的负载只能通过计算变化的次数这一修 正值来计算。
Linux内核定义一个长度为3的双字数组avenrun,以计算三个负载,双字的低11位用于存放负载的小数部分,高21位用于存放整数部分。
1 |
#define FSHIFT 11 /* nr of bits of precision */ |
2 |
#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point(定点) */ |
有点类似于把小数乘以10000,然后当整数运算。最后再除以10000和取模得到小数。
转载请注明:旅途@KryptosX » Linux/Unix中的load average