Calculating the load average in the freebsd kernel
Kannan Varadhan
kannanv at juniper.net
Fri Aug 19 19:08:01 GMT 2005
Hello,
I am staring at the code in kern/kern_synch.c that calculates the load
average of the system, and I cannot fully understand how the freebsd version
works. Specifically, it looks as:
/*
* Constants for averages over 1, 5, and 15 minutes
* when sampling at 5 second intervals.
*/
static fixpt_t cexp[3] = {
0.9200444146293232 * FSCALE, /* exp(-1/12) */
0.9834714538216174 * FSCALE, /* exp(-1/60) */
0.9944598480048967 * FSCALE, /* exp(-1/180) */
};
...
/*
* Compute a tenex style load average of a quantity on
* 1, 5 and 15 minute intervals.
* XXXKSE Needs complete rewrite when correct info is available.
* Completely Bogus.. only works with 1:1 (but compiles ok now :-)
*/
static void
loadav(void *arg)
{
int i, nrun;
struct loadavg *avg;
nrun = sched_load();
avg = &averunnable;
for (i = 0; i < 3; i++)
avg->ldavg[i] = (cexp[i] * avg->ldavg[i] +
nrun * FSCALE * (FSCALE - cexp[i])) >> FSHIFT;
...
And elsewhere, FSCALE is defined as 1<<FSHIFT, and FSHIFT is 11.
Focusing only the formula, then
avg->ldavg[i] = (cexp[i] * avg->ldavg[i] +
nrun * FSCALE * (FSCALE - cexp[i])) >> FSHIFT;
^^^^^^
Why do we have that extra FSCALE multiplier in the second term? If I do
some logical simplifications, this seems to get me:
(\alpha * FSCALE * ldavg[I] + nrum * FSCALE * FSCALE (1 - \alpha)) >> FSHIFT
I.e.
\alpha * ldavg[I] + nrun * FSCALE * (1 - \alpha)
What am I missing in this arithmetic?
Thanks,
Kannan
More information about the freebsd-questions
mailing list