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:
67 #define CALC_LOAD(load,exp,n) \
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
> 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
> _______________________________________________
> 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"
More information about the freebsd-questions
mailing list