Subject: speeding up microtime
To: None <port-i386@netbsd.org>
From: David Laight <david@l8s.co.uk>
List: port-i386
Date: 08/01/2002 15:19:41
I've just down some performance measurements on (another)
rewrite of the i386 microtime.

This cut the execution time for gettimeofday() call from
about 6.3us to 4.1us by removing 2 of the 4 'inb' instructions
from the usual code path.
I expect the 'standard' code takes 5us since I'd already made
other changes to the same bit of code.

The 'trick' is to realise that you don't need to close the
timer latch.  As the counter is running at ~1MHz it won't
decrement far between reading the low and high nibbles.
So the code can be:

	# Read down counter - ignore latch!
	# If the lsb we read is close to zero, msb might be wrong
	inb	$TIMER_CNTR0,%al	# lsb to %dl
	movb	%al,%dl
	inb	$TIMER_CNTR0,%al	# msb to %cl
	mov	%al,%cl
	cmpb	$4,%dl			# might lsb have wrapped before ...
	ja	1f			# ... we read msb - j if not
	inb	$TIMER_CNTR0,%al	# reread, discard first lsb
	movb	%al,%dl
	inb	$TIMER_CNTR0,%al	# msb
	cmpb	%al,%cl			# if msb changed, take first msb
	je	1f
	movb	$1,%dl			# and minimal lsb
1:
	inb	$IO_ICU1,%al		# grab interrupt pending from ICU
	movb	%al,%ch			# fairly briskly
	movb	%cl,%al

It doesn't surprise me that the 'inb' calls take ~1us,
except that you might have thought that the io devices integrated
into the south bridge would run slightly faster than their
original ISA counterparts.
I suspect it is down to compatibility...

	David

-- 
David Laight: david@l8s.co.uk