From owner-freebsd-current@FreeBSD.ORG Sun Jan 25 00:53:39 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4C40F16A4CE for ; Sun, 25 Jan 2004 00:53:39 -0800 (PST) Received: from mailout1.pacific.net.au (mailout1.pacific.net.au [61.8.0.84]) by mx1.FreeBSD.org (Postfix) with ESMTP id B2CA543D39 for ; Sun, 25 Jan 2004 00:53:36 -0800 (PST) (envelope-from bde@zeta.org.au) Received: from mailproxy1.pacific.net.au (mailproxy1.pacific.net.au [61.8.0.86])i0P8rTLE018985; Sun, 25 Jan 2004 19:53:29 +1100 Received: from gamplex.bde.org (katana.zip.com.au [61.8.7.246]) i0P8rPdC023836; Sun, 25 Jan 2004 19:53:27 +1100 Date: Sun, 25 Jan 2004 19:53:26 +1100 (EST) From: Bruce Evans X-X-Sender: bde@gamplex.bde.org To: Poul-Henning Kamp In-Reply-To: <44827.1074974041@critter.freebsd.dk> Message-ID: <20040125183335.B30359@gamplex.bde.org> References: <44827.1074974041@critter.freebsd.dk> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: 'Bill Moran' cc: current@freebsd.org Subject: Re: DragonflyBSD kernel clock improvements X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 25 Jan 2004 08:53:39 -0000 On Sat, 24 Jan 2004, Poul-Henning Kamp wrote: > In message <200401241948.i0OJmDpo036688@apollo.backplane.com>, Matthew Dillon w > rites: > > There are a couple of things going on here... it isn't all just fluff. > > > > First, the basic problem is that nanosleep() (aka sleep() aka > > usleep()) consistently sleeps for far longer then the requested time. > > I think this was subject to Brucification last it was raised on our > lists. Do you mean "subject to getting the details right"? [Some context recovered] > > Second, the fractional compensation code for the 8254. The 8254 runs > > at 1193182 Hz. If your 'hz' is set to 100, a fixed clock reload value > > of 11931 looses significant precision. The higher your 'hz' setting, > > the more precision is lost and the greater the error verses real time. (The rounding is actually to nearest so 1193182 / 100 is rounded to 11932, not 11931.) 1193182 is only a nominal frequency. On machines I'm running right now, the actual frequency is 1193202, 1193211 and 1193276 (+-2 most days). So using the default of 11932 loses quite a bit to both accuracy and precision. However, small errors are unimportant in most or all applications, and the accuracy is easy to fix using "sysctl machdep.i8254_freq=whatever". I set all my clocks using the relevant sysctl so that they are all as accurate as possible. For the i8254 clock, the best possible is 0.5 / 1193182 seconds or about 0.5 ppm, since fractional frequencies can't be set. 0.5 ppm is a good practical accuracy to aim for since the frequencies of all clocks on all my machines drift with the temperature by about +- 2 ppm every day. I try for 0.1 ppm long term accuracy using the TSC timecounter and only use other timecounters for testing. > > If you are using the 8254 as your wallclock, then you will see a > > significant 'speed up' of the wall clock at higher hz settings. > Unless you have replaced timecounters this is not true. Timecounters > are insensitive to how your Hz ticks, as long as it does it often > enough. (You should probably pull in the code from -current though, > the 4.x code has some marginal issues). > > > hz will wind up being far higher then the true frequency you > > requested. It isn't just jitter... it's a permanent error factor and > > it can create significant problems if you are running ntpd. > > Only if you replaced timecounters. Indeed. The long-term drift from lost precision in scaling 1193182 by HZ is zero, and the long-term drift from 1193182 being accurate is whatever it is (can be quite large). After fixing the inaccuracy as above, the long-term drift due to innacuracy is significantly smaller than the combination of short-term drifts due to nondeterministic temperature. ntp can handle innacuracy well enough (better than it can handle short-term drifts) provided it is not too large (too large is hundreds of ppm). Short-term innaccuracy and imprecision is seen mainly by select() and related timeouts, but it doesn't really matter in most cases since it doesn't (or shouldn't) get a chance to build up. E.g., if there is an off-by-1 error setting the i8254 maxiumum count, then the period between timeouts will be wrong by about 1 usec (1/1193182). 1 usec just doesn't matter even on a pseudo-real-time system because interrupt latency is more than that even without -current's pessimization of interrupts. The inaccuracy can build up in some cases, but not in places like nanotime() which don't simply count off a number of ticks. nanotime()'s innacuracy has differenct sources. > > Third, if you are not using the 8254 for your wallclock there will be > > persistent drift between clocks based on the 8254's hz-based interface > > (ticks) and clocks based on realtime. The PLL part of the fix simply > > compensates for the 8254's constant drift relative to the wallclock > > by occassionally adding one or subtracting one from the 8254's reload > > value. > > This is harmless but IMO also pointless. Setting the frequencies of all the clocks as above gives this to within the precision of the frequency setting. Synchronizing the frequencies is useful mainly for testing. It's annoying for ntp to see large changes in the drift when you switch the timecounter. Keeping the nominal frequencies of all the clocks relatively correct to within 0.5 ppm limits the drift to this amount and ntp can't tell the difference between this and a drift from temperature changes. Bruce