# Calculating the load average in the freebsd kernel

Kannan Varadhan kannanv at juniper.net
Fri Aug 19 21:25:12 GMT 2005

Thanks Chris.

Yes, I did see that earlier.  Two things about it:

1.  It is for the linux kernel.
Interestingly, the linux kernel is almost close enough to the BSD
kernel, particularly in the choice of constants and usage, although in
atypical convolutions.  The main difference is in how it is an unfolded
expression, which makes it hard to follow immediately, and in the formula
itself, for which, ...

2.  The linux formula though is:

68         load *= exp; \
69         load += n*(FIXED_1-exp); \
70         load >>= FSHIFT;

Which is    load = ((load * exp) + n * (f_1 - exp)) >> FSHIFT.
Exp is really (in BSD speak) FSCALE * \alpha, f_1 is FSCALE, so this formula
boils down to (\alpha * load) + nrun * (1 - \alpha), a nice clean formula.

Thanks,

Kannan

On 8/19/05 1:58 PM, "Chris St Denis" <chris at aebc.com> wrote:

> This may help
>
> http://www.teamquest.com/resources/gunther/ldavg1.shtml
>
> -----Original Message-----
> From: owner-freebsd-questions at freebsd.org
> [mailto:owner-freebsd-questions at freebsd.org] On Behalf Of Kannan Varadhan
> Sent: Friday, August 19, 2005 12:08 PM
> To: freebsd-questions at freebsd.org
> Subject: Calculating the load average in the freebsd kernel
>
> 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
> {
>         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
> _______________________________________________
> freebsd-questions at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-questions
> To unsubscribe, send any mail to "freebsd-questions-unsubscribe at freebsd.org"