Date: Sun, 26 Nov 1995 15:59:10 +1100 From: Bruce Evans <bde@zeta.org.au> To: current@FreeBSD.ORG, phk@freefall.freebsd.org Subject: Re: pentiums, clocks and xntpd: a smoking gun... Message-ID: <199511260459.PAA15785@godzilla.zeta.org.au>
next in thread | raw e-mail | index | archive | help
>I hooked a DCF77 receiver up to my Pentium/133 and here is my findings:
>My microtime() drifts at a rate of:
> (7.679466-5.081014)/(76710.567-75815.162) = .002901
>this is ten and a half second per hour :-(
>It is surprisingly close to the ratio of:
> (133.333333-133)/133 = .002506
>If this was the case, then my residual drift would be .000395,
>or one and a half second per hour.
Upgrade to a Pentium/100 ;-).
Print the clock frequency in calibrate_cyclecounter() before dividing by
1000000. The 8254 clock may be a bit more accurate than 2901 ppm. The
ones on my main systems are accurate to about +700 ppm and -300 ppm.
I think the correct fix to these problems is:
Pentium clock:
1. Increase the resolution of pentium_mhz. Either store it in hz and
calculate:
delta_usec = (delta_TSC * 1000000) / pentium_hz
(ensure that delta_TSC is small so that this doesn't overflow) or
store it in fixed point and calculate:
delta_usec = (delta_TSC * frac) >> shift;
2. Implement `sysctl -w pentium_hz=value' or the fixed point version
of this.
3. For each system, determine the best value for pentium_hz and set
it in /etc/rc using sysctl.
8254 clock:
4.-6. Same as 1.-3. except for the 8254 clock instead of the Pentium
clock.
7. Implement `sysctl -w timer0_max_count=value'.
8. For each system, determine the best value for timer0_max_count
and set it in /etc/rc using sysctl. Do this even on Pentiums
to make the clock interrupt frequency as close as possible to
`hz'.
General:
9. Make microtime() aware of adjustments to the clock. This involves
scaling microtime()'s clock by ((tick + tickdelta) / tick) and
perhaps adding the phase adjustment.
10. Implement a private version of `time_adj' and a sysctl to set it.
The point of this is to handle lost resolution due to the value
returned by CPU_THISTICKLEN() being measured in usec. The
phase adjustment could be kept track of in CPU_THISTICKLEN()
but it seems better to use the existing phase adjustment code
in hardclock().
11. For each system, determine the best value for the private
`time_adj' and set it in /etc/rc using sysctl.
Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199511260459.PAA15785>
