[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

MiNT 1.11 BETA: optimize loadavg calculation



This patch optimizes the loadavg calculation a bit:

- make uptimetick short instead of long, the same for some more vars
  in proc.c
- in the 200hz timer, just decrement uptimetick
- in the vbl intr if uptimetick < 0 call calc_load_average
- in calc_load_average just add 200 to uptimetick, this way we never
  lose an interrupt (unless vbl is blocked for more than 32768/200 =
  163 seconds :-)
- uptime_vbl deleted, checkbttys_vbl moved to intr.spp
- gen_average changed to not to use that many arguments, only three
  are needed

There are some more optimisations in intr.spp to save some cycles.

--- orig/intr.spp	Mon Aug  8 05:01:36 1994
+++ intr.spp	Mon Aug 15 20:27:42 1994
@@ -35,29 +35,23 @@
 	XREF	_leave_kernel
 	XREF	_preempt
 	XREF	_in_kernel
-	XREF	_uptime_vbl
+	XREF	_calc_load_average
 	XREF	_uptimetick
+	XREF	_checkbttys_vbl
 
 ; AKP: this code is hit once every 5ms; it updates the time fields of curproc.
 _mint_5ms:
 	move.l	a0,-(sp)
-	lea	_uptimetick,a0
-	tst.l	(a0)
-	bne.s	L_no_uptime
-	move.l	#200,(a0)
-L_no_uptime:
-	subq.l	#1,(a0)
+	subq.w	#1,_uptimetick
 	move.l	_curproc,a0
 	tst.w	_in_kernel
 	bne.s	L_systime
-	lea	P_USRTIME(a0),a0	; get offset to curproc->usrtime
-	addq.l	#5,(a0)			; update the time
+	addq.l	#5,P_USRTIME(a0)	; update curproc->usrtime
 	move.l	(sp)+,a0
 	move.l	_old_5ms+8,-(sp)	; branch to old vector
 	rts
 L_systime:
-	lea	P_SYSTIME(a0),a0	; get offset to curproc->systime
-	addq.l	#5,(a0)
+	addq.l	#5,P_SYSTIME(a0)	; update curproc->systime
 	move.l	(sp)+,a0
 	move.l	_old_5ms+8,-(sp)
 	rts
@@ -82,9 +76,13 @@
 	rts
 
 L_comeback:
+	jsr	_checkbttys_vbl
+	tst.w	_uptimetick
+	bgt.s	L_no_uptime
 	movem.l	d0-d2/a0-a2,-(sp)	; save C registers
-	jsr	_uptime_vbl		; Go test if it's time to update uptime
+	jsr	_calc_load_average	; Go test if it's time to update uptime
 	movem.l	(sp)+,d0-d2/a0-a2
+L_no_uptime:
 	tst.w	_proc_clock		; has time expired yet?
 	beq.s	L_expired		; yes -- maybe go switch processes
 L_out:
@@ -136,8 +134,7 @@
 _reset:
 	move.w	#$2700,sr		; avoid interruption here
 	move.l	sp,_init_tail		; save A7
-	lea	_init_tail,sp		; set up temporary stack
-	lea	256(sp),sp
+	lea	_init_tail+256,sp	; set up temporary stack
 	movem.l	d0-d2/a0-a2,-(sp)	; save C registers
 	jsr	_restr_intr		; restore interrupts
 	movem.l	(sp)+,d0-d2/a0-a2	; restore registers
--- orig/proc.c	Mon Aug 15 20:59:48 1994
+++ proc.c	Mon Aug 15 20:56:50 1994
@@ -721,9 +721,9 @@
 
 unsigned long uptime = 0;
 unsigned long avenrun[3] = {0,0,0};
-unsigned long uptimetick = 0;
-static unsigned long number_running;
-static unsigned long one_min_ptr = 0, five_min_ptr = 0, fifteen_min_ptr = 0;
+short uptimetick = 200;
+static int number_running;
+static int one_min_ptr = 0, five_min_ptr = 0, fifteen_min_ptr = 0;
 static unsigned long sum1 = 0, sum5 = 0, sum15 = 0;
 static unsigned char one_min[SAMPS_PER_MIN];
 static unsigned char five_min[SAMPS_PER_5MIN];
@@ -751,26 +751,20 @@
 }
 
 unsigned long
-gen_average(sum, cur_load, load_array, ptr, max_size)
+gen_average(sum, load_ptr, max_size)
 	unsigned long *sum;
-	unsigned long cur_load;
-	unsigned char load_array[];
-	unsigned long ptr;
+	unsigned char *load_ptr;
 	int max_size;
 {
-	unsigned long retval;
-	long old_load, new_load;
-
-	old_load = (long)load_array[ptr];
-
-	new_load = (long)cur_load;
-	load_array[ptr] = (char)new_load; 
+	int old_load, new_load;
 
-	*sum += ((new_load - old_load) * LOAD_SCALE);
+	old_load = (int) *load_ptr;
+	new_load = number_running;
+	*load_ptr = (char)new_load; 
 
-	retval = (unsigned long)(*sum / max_size);
+	*sum += ((long) (new_load - old_load) * LOAD_SCALE);
 
-	return retval;
+	return (*sum / max_size);
 }
 
 void
@@ -767,6 +773,7 @@
 	PROC *p;
 
 	uptime++;
+	uptimetick += 200;
 
 	if (uptime % 5) return;
 
@@ -779,35 +784,22 @@
 			if ((p->wait_q == 0) || (p->wait_q == 1))
 				number_running++;
 
-	avenrun[0] = gen_average(&sum1, number_running,
-		one_min, one_min_ptr++, SAMPS_PER_MIN);
+	avenrun[0] = gen_average(&sum1, &one_min[one_min_ptr++],
+				 SAMPS_PER_MIN);
 
 	if (one_min_ptr == SAMPS_PER_MIN)
 		one_min_ptr = 0;
 
-	avenrun[1] = gen_average(&sum5, number_running,
-		five_min, five_min_ptr++, SAMPS_PER_5MIN);
+	avenrun[1] = gen_average(&sum5, &five_min[five_min_ptr++],
+				 SAMPS_PER_5MIN);
 
 	if (five_min_ptr == SAMPS_PER_5MIN)
 		five_min_ptr = 0;
 
-	avenrun[2] = gen_average(&sum15, number_running,
-		fifteen_min, fifteen_min_ptr++, SAMPS_PER_15MIN);
+	avenrun[2] = gen_average(&sum15, &fifteen_min[fifteen_min_ptr++],
+				 SAMPS_PER_15MIN);
 
 	if (fifteen_min_ptr == SAMPS_PER_15MIN)
 		fifteen_min_ptr = 0;
 
-}
-
-static unsigned long last_200ms = 0;
-
-void uptime_vbl()
-{
-	unsigned long myuptick = uptimetick;
-	
-	checkbttys_vbl();
-	if (myuptick > last_200ms)
-		calc_load_average();
-
-	last_200ms = myuptick;
 }
--- orig/proto.h	Mon Aug  8 08:42:30 1994
+++ proto.h	Mon Aug 15 19:10:28 1994
@@ -275,8 +275,7 @@
 void ARGS_ON_STACK wakeselect P_((long param));
 void DUMPPROC P_((void));
 void calc_load_average P_((void));
-unsigned long gen_average P_((unsigned long *sum, unsigned long cur_load, unsigned char load_array[], unsigned long ptr, int max_size));
-void uptime_vbl P_((void));
+unsigned long gen_average P_((unsigned long *sum, unsigned char *load_ptr, int max_size));
 
 /* signal.c */
 long killgroup P_((int pgrp, int sig));