[net.sources] new 4.2 loadav

mahler@pur-ee.UUCP (Mahler) (08/29/84)

With a mailbox full of requests, I need to post this ...
... here is a copy of the loadav paper.  Your comments about
the paper and your use of the routine would be appreciated ... tnxs ... Steve
p.s. - use the "ms" macro package

For those of you who recieved a truncated copy ... sorry ... Please place
this file in the editor and after "cutting here" edit
1,$s/^X//
good luck ... Steve

---- cut here ----
X.ps 12
X.vs 14
X.nr PS 12
X.nr VS 14
X.de ZZ
X\s-2
X..
X.de ZY
X\s+2
X..
X.ig
X$Header$
X$Log$
X..
X.DA June 1984
X.EH "'Load Average Algorithm'- % -'Load Average Algorithm'"
X.OH "'Load Average Algorithm'- % -'Load Average Algorithm'"
X.OF "'Purdue \s-1ECN\s+1'\*(DY'Simmons/Mahler/Curry'"
X.EF "'Simmons/Mahler/Curry'\*(DY'Purdue \s-1ECN\s+1'"
X.RP
X.TL
XA New Load Average Algorithm
Xfor \s-14.2 BSD\s+1
X.UX
X.AU
XWilliam R. Simmons
X.AU
XStephen J. Mahler
X.AU
XDavid A. Curry
X.AI
XEngineering Computer Network
XSchool of Electrical Engineering
XPurdue University
XWest Lafayette, Indiana 47907
X.AB
XThis paper describes briefly a direct method of computing 
X\s-1VAX 4.2BSD\s+1
X.UX
XSystem load averages.
XThe load average algorithm supplied with
X\s-14.2 BSD\s+1
X.UX
Xuses an approximation algorithm to calculate its values.
XWhile the approximation is reasonable in some computing
Xenvironments,
Xits error is significant under rapidly changing load conditions.
XThe direct method presented here provides the actual load averages
Xfor the prescribed time intervals.
XSuch values allow much more definitive use and interpretation by system
Xand user programs making decisions based on system load.
X.AE
X.ig
X$Header$
X$Log$
X..
X.NH 1
XIntroduction
X.PP
XThis paper describes an implementation for directly computing load averages
Xon \s-14.2 BSD\s+1
X.UX .
XAs supplied by the University of California at Berkeley,
Xthe \s-14.2 BSD\s+1 kernel maintains three load averages in
Xdouble precision floating point form.
XThese numbers represent the load average over the past one,
Xfive,
Xand fifteen
Xminutes respectively.
XThe numbers are stored in the array
X.B avenrun ,
Xmaintained by the routines within
X.I vm_sched.c .
XBecause of the needs of the networking software,
Xthe Purdue Engineering Computer Network staff increased the
Xsize of the
X.B avenrun
Xarray to five by adding a five second load average
Xand an instantaneous count of jobs in the run queue.
XThis addition did not seriously affect the supplied algorithm,
Xit merely added another time window computation to those already being
Xperformed.
X.ig
X$Header$
X$Log$
X..
X.NH 1
XThe Standard \s-14.2 BSD\s+1 Algorithm
X.PP
XThe load average algorithm supplied with \s-14.2 BSD\s+1 uses an
Xexponential to compute the load average values.
XEach load average is calculated using the formula
X.EQ C
X{avg sub i} ~=~ {cexp sub i} ~\(mu~ {avg sub i} ~+~ n ~\(mu~ (1.0 ~-~ {cexp sub i})
X.EN
X.LP
Xwhere
X.B avg
Xis the load average,
X.B cexp
Xis an exponential constant,
Xand
X.B n
Xis the number of jobs in the run queue.
XThe exponential constants are computed as
X.EQ C
X{cexp sub i} ~=~ {e sup {-1 over {tau sub i}}}
X.EN
X.EQ C
X{tau sub i} ~=~ 12 ~\(mu~ [load~~average~~time~~in~~minutes]
X.EN
X.LP
XThe exponential constants used in the calculations have been adjusted
Xto ``forget'' 90% of their
Xvalues in five ``load average times.''
XThus,
Xthe five minute load average,
Xwith a constant input of zero,
Xwill decay to 90% of its original value in 25 minutes.
X.PP
XThe algorithm was evaluated by plotting \s-1ECN\s+1 load data collected
Xduring normal operations.
XThe results indicated that the Berkeley algorithm produced numbers which
Xdid not represent the true machine load.
XBecause of the damping property of the exponential,
Xlarge changes in the number of runnable jobs did not affect the
Xcalculated load average unless the change
Xpersisted for an extended period of time.
XInaccuracies became more significant when the number of jobs
Xin the run queue rose above ten, or when the number fluctuated over
Xa large range.
X.ig
X$Header$
X$Log$
X..
X.NH 1
XThe New Algorithm
X.PP
XAfter testing the \s-14.2 BSD\s+1 algorithm
Xand finding it suboptimal,
Xwe began to discuss the possibilities of writing a new algorithm.
XFirst the constants used in the present
Xalgorithm were changed such that the results increased and decreased more
Xrapidly.
XHowever,
Xexperimentation proved that the desired result was not yet achieved.
XSecond,
Xa true mathematical average was computed.
XThat is,
Xa history of the past
X.I n
Xload averages was stored and averaged.
X.PP
XAfter implementing the algorithm in a user-level program,
Xit was tested on the same data used previously to test the old algorithm.
XUnlike the old algorithm,
Xhowever,
Xthe new routine \fIfelt\fP even the slightest change in the number
Xof runnable jobs (well, it should have,
Xit is a true
X.I mathematical
X.I average ),
Xand the load averages changed accordingly.
XThe algorithm was declared successful.
XThe next step was to compare the two algorithms for speed and size.
XThe new algorithm,
Xalthough it took up more space (approximately 512 bytes more than
Xthe old algorithm),
Xwas no slower than the algorithm presently being used in the kernel.
X.PP
XThe final test of the algorithm was to install it in the kernel.
XAfter a brief problem introduced when ``hand optimizing'' the code,
Xthe algorithm was up and running,
Xand has been ever since.
X.NH 2
XAlgorithm Startup
X.PP
XDuring the first time period for the algorithm (immediately after the
Xmachine is booted),
Xthe algorithm assumes that the load average has consistently been zero
Xover all past time.
XFor this reason,
Xthe load average will not decay until at least one time window (in our
Xcase, the fifteen minutes for the last load average) has passed.
XWe consider this a minor annoyance,
Xbut not worth the overhead and complexity to fix.
X.EH "'The \s-14.2 BSD\s+1 Algorithm'- % -'Load Average Algorithm'"
X.OH "'Load Average Algorithm'- % -'The \s-14.2 BSD\s+1 Algorithm'"
X.bp
X.ig
X$Header$
X$Log$
X..
X.B
X.ce
XAppendix A \(em The \s-14.2 BSD\s+1 Algorithm
X.R
X.nf
X.sp .5i
X.ta 5m 10m 15m 20m 25m 30m 35m 40m 45m 50m 55m 60m
Xcexp[0] \(eq 0.36787944117144250000		/* 5 sec. e(-1/1)	*/
Xcexp[1] \(eq 0.92004441462932320000		/* 1 min. e(-1/12)	*/
Xcexp[2] \(eq 0.98347145382161740000		/* 5 min. e(-1/60)	*/
Xcexp[3] \(eq 0.99445984800489670000		/* 15 min. e(-1/180)	*/
X
X/*
X * avg is a pointer to the avenrun[] array, n is the
X * number of jobs in the run queue.
X */
X
X	for (i = 0; i < 4; i++)
X		avg[i] = cexp[i] * avg[i] + n * (1.0 - cexp[i]);
X	avg[4] = n;	/* last one is raw */
X.fi
X.EH "'The Purdue \s-1ECN\s+1 Algorithm'- % -'Load Average Algorithm'"
X.OH "'Load Average Algorithm'- % -'The Purdue \s-1ECN\s+1 Algorithm'"
X.bp
X.ig
X$Header$
X$Log$
X..
X.B
X.ce
XAppendix B \(em The Purdue \s-1ECN\s+1 Algorithm
X.R
X.nf
X.sp .5i
X.ta 5m 10m 15m 20m 25m 30m 35m 40m 45m 50m 55m 60m
X/*
X * loadav - compute load averages, Purdue EE version.
X *
X * Rather than using an exponential as the standard Berkeley kernel
X * does, this routine keeps the last LBSIZE numbers in a circular
X * buffer and uses them to compute actual averages.  The lb array
X * stores the numbers, the accum array contains the sums of the
X * appropriate count of the numbers.
X *
X * The divisors array contains floating point numbers, each number
X * represents the number of 5-second intervals contained in the
X * corresponding load average time interval.
X *
X * The tails array contains pointers to the various ends of the
X * "windows" used in the sums.  These should correspond to the 
X * divisors array.
X *
X * The order of avenrun[] on Purdue systems is:
X *
X *	avenrun[0]	-	1 minute load average
X *	       [1]	-	5 minute
X *	       [2]	-	15 minute
X *	       [3]	-	5 second
X *	       [4]	-	raw (no. of jobs in runq + disk wait)
X *
X * LB should be at least ([longest loadav time] / [5 seconds]) + 2
X * elements large.  5 seconds is the time interval between calls
X * to this routine.
X *
X * Arguments: avg is a pointer to the avenrun[] array, n is the number
X *	      of jobs in the run queue.
X *
X * This routine lives in sys/vm_sched.c
X *
X * David A. Curry / Stephen J. Mahler, 5/22/84
X */
X
X#define LB		256
X	
Xloadav(avg, n)
Xregister double *avg;
Xregister int n;
X{
X	register int i;
X	static unsigned short lb[LB];
X	static unsigned short *head = lb;
X	static unsigned short *lbend = &lb[LB];
X	static unsigned short accum[5] = { 0, 0, 0, 0, 0 };
X	static double divisors[5] = { 12.0, 60.0, 180.0, 2.0, 1.0 };
X	static unsigned short *tails[5] = 
X		{ &lb[LB-12], &lb[LB-60], &lb[LB-180], &lb[LB-2], &lb[0] };
X	
X	*head = avg[4] = n;
X	
X	if (++head == lbend)
X		head = lb;
X
X	for (i=0; i < 4; i++) {
X		accum[i] = accum[i] - *tails[i] + n;
X		avg[i] = (double) accum[i] / divisors[i];
X		
X		if (++tails[i] == lbend)
X			tails[i] = lb;
X	}
X}

jeff@voder.UUCP (Jeff Gilliam) (09/12/84)

Please be aware that if you install Purdue's modified loadav() routine
you must also change the definitions of avenrun[] in sys/vm_sched.c
(~ line 37) and h/kernel.h (~ line 24).  If you do not, the results
are *heh, heh* unpredictable.

old:
double	avenrun[3];

new:
double	avenrun[5];

-- 

Jeff Gilliam	{ucbvax,ihnp4!nsc}!voder!jeff