[REVIEW/TEST] nanodelay() vs DELAY()

From: Poul-Henning Kamp <phk_at_phk.freebsd.dk>
Date: Fri, 19 Nov 2004 10:37:57 +0100
A number of device drivers need to have predictable small delays and
today they largely rely on DELAY() for that.

Problem is, DELAY sucks for durations below 10-20 usec.

I have written a first cut of a self-calibrating nanodelay() which
is better three orders of magnitude further down.

The patch can be found at in p4::phk_dev or

	http://phk.freebsd.dk/patch/nanodelay.patch

nanodelay() takes a nanosecond argument and will try to sleep exactly
that many nanoseconds but never less than that.

With a primed cache, the performance is close to perfect from 200nsec
and up, and below that it depends a lot on the speed of the machine.

Without a primed cache, an unpredictable jitter will be superimposed
on the delay duration.

Here is a plot which shows how DELAY() and nanodelay() perform on two
of my test-machines:

	http://phk.freebsd.dk/misc/nanodelay.png

I would appreciate if driver writers could play with this and
see if makes any difference anywhere.

Please notice that this is a timed cpu-spin, it does not allow
another thread to use the CPU, so it should only be used for
short (< 1/hz) delays.

How it works:

A default routine spins on the timecounter using nanouptime().  How
well this works depends on which timecounter we use, but in general
we can trust it to be OK above a few microseconds.

An array contains function+arg to use for delays less than 8 usec,
for longer delays the timecounter routine is always called.

Each bucket in the array spans 8 nanoseconds, so delays of
0-7 nanoseconds use bucket 0, 8-15 nsec use bucket 1 etc.

A number of cpu based spin routines are calibrated against the
timecounter for various argument values and plugged into the array
accordingly.

The array takes up 9000 bytes on 32 bit and 17000 on 64 bit.  This
can be reduced at the cost of reduced precision in nanodelay(), we
need to determine the correct tradeoff there.

-- 
Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
phk_at_FreeBSD.ORG         | TCP/IP since RFC 956
FreeBSD committer       | BSD since 4.3-tahoe
Never attribute to malice what can adequately be explained by incompetence.
Received on Fri Nov 19 2004 - 08:38:00 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:22 UTC