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].