On Wed, Aug 05, 2015 at 10:33:12PM +1200, Bryan Christianson wrote:
> I had a look at this method and tried a few others as well with no success. 
> Then I realised that at the end of stop_adjust() we have:
> 
> offset_register += current_freq * elapsed_plus_adjust - adjustment_remaining;
> 
> Now, when the system is stable, adjustment_remaining will be small and 
> elapsed_plus_adjust will be close to DRIFT_REMOVAL_INTERVAL (1 second) when 
> the drift removal timer fires. On this machine the clock slews at 2ms / 
> second and the adjtime() has completed in just a few 10s of usecs. So 
> offset_register will contain a value close to current_frequency, which is 
> what I am observing.

I think that's how it's supposed to work.

> This also explains why using DRIFT_REMOVAL_INTERVAL of 0.1s reduces the 
> offset significantly. We make more frequent calls to adjtim() and 
> consequently less time is spent with the clock free running and 
> elapsed_plus_adjust has a smaller value.

That makes sense. The precompensation I was thinking was about moving
the mean offset closer to zero. For example, if the clock has a drift
of 100 ppm, the offset would be moving somewhere around around 0 +/-
50 microseconds, instead of 50 +/- 50 microseconds.

Something like this (not tested):

@@ -119,7 +119,7 @@ start_adjust(void)
   }

   UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
-  accrued_error = elapsed * current_freq;
+  accrued_error = (elapsed + DRIFT_REMOVAL_INTERVAL / 2.0) * current_freq;

   adjust_required = - (accrued_error + offset_register);


> This suggests we should probably look at your idea of making 
> DRIFT_REMOVAL_INTERVAL dynamic, although I am not sure what the criteria 
> would be for adjusting it. Possibly an initial value of 1.0s, a minimum 
> interval of 0.1s and a maximum of 4.0s (1/2 the minimum poll period).

Dynamic drift removal interval would allow us to control the maximum
offset. Maybe it could be even done without a fixed maximum interval.
A suitable interval could be determined from the drift and the offset
sd value (or possibly the correction rate parameter passed to the
accrue_offset() driver function). If we know the tracked NTP time is
good only to 1 millisecond and the drift of the clock is just 5 ppm,
allowing the offset to reach millisecond by setting the interval to
200 seconds would still be acceptable I think.

This could help with power saving when using (distant) public NTP
servers. Isn't the ntpd in Mac OS X patched to avoid waking up too
frequently?

> One possibility would be to make adjustments by 10% (or some other value 
> between 0 and 1) depending on the value of adjustment_remaining - i.e. run 
> drift removal less frequently if adjustments are not completing and more 
> frequently otherwise. Might need to use some sort of filtering to prevent 
> toggling of the value every other update.

Wouldn't that make the interval too short in most cases?

>       if(adjustment_remaining != 0) {
>               drift_removal_interval = MIN(drift_removal_interval * 1.1, 
> MAX_DRIFT_REMOVAL_INTERVAL)
>       } else {
>               drift_removal_interval = MAX(drift_removal_interval / 1.1, 
> MIN_DRIFT_REMOVAL_INTERVAL)
>       }

-- 
Miroslav Lichvar

-- 
To unsubscribe email [email protected] with "unsubscribe" 
in the subject.
For help email [email protected] with "help" in the 
subject.
Trouble?  Email [email protected].

Reply via email to