> On 4/08/2015, at 3:52 am, Miroslav Lichvar <[email protected]> wrote:
> 
> I was wondering if the error of the clock could be minimized by
> including in the requested adjustment a prediction of the offset in
> the middle of the update interval so the mean value is close to zero
> if the drift doesn't change much. E.g. with a drift of 10 ppm and
> current offset of 20 microseconds, request 25 microsecond adjustment
> instead of 20, so the clock overshoots a bit and reaches zero offset
> in about 0.5 seconds.
> 

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.

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.

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

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.

        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)
        }

-- 
Bryan Christianson


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