[time-nuts] looking for good description/generalized model for time adjustments

Hal Murray hmurray at megapathdsl.net
Wed Jul 29 18:44:43 UTC 2009


> I'm looking for a good (short) description and/or a generalized model
> for relating a local time counter to some external reference.  Here's
> the scenario.. A computer has a local clock that is a counter being
> driven by a local oscillator. Periodically, we get "time updates" from
> some outside source that give an "absolute time" and a sync.

What sort of accuracy do you want?  seconds?  milliseconds?  microseconds?

What sort of computer?  A big one where you can run lots of software or a 
tiny one where every instruction counts?  How stable is the environment 
(temperature)?

The trick is to think of frequency rather than time.

The usual problem with clock drift is that the local oscillator is off 
slightly, typically a few 10s of ppm.  You can fix most of that if you can 
fudge the frequency of the clock.  Say your system is updating the time from 
an interrupt that goes off every ms and you are keeping time in ms.

The old code would look something like:
  ms = ms + 1
  if ms == 1000 { sec = sec + 1; ms = 0}

The first step is to change that to:
  ns = ns + 1000000
  if ns == 1000000 {ms = ms + 1; ns = 0}
  if ms == 1000 { sec = sec + 1; ms = 0}

The trick is you want to change that first 1000000 to match what the osc is 
actually delivering.  So the code looks like:
initialize:  nspertick = 1000000 + ppmfudge
run time:
  ns = ns + nspertick
  while ns >= 1000000 {ms = ms + 1; ns = ns - 1000000}
  if ms == 1000 { sec = sec + 1; ms = 0}

if ppmfudge is negative, you will skip occasional updates to ms (drop ticks).
if ppmfudge is positive, you will occasionally jump by 2 ms.

I picked ms and ns for this example since the numbers work out conveniently 
for an integer fudge factor in ppm.  You will need more bits for finer 
control.

1 ppm is 0.08 seconds per day or 1/2 second per week.

With that sort of setup, and a stable clock (temperature?) you can get within 
a few seconds per week by hand.

If you want to get the human out of the loop, you can implement a PLL.  That 
gets complicated with filtering and stability and such.

Have you looked into ntp?  The fudge factor is usually called drift.  It's 
usually stored in /etc/ntp/drift or /var/lib/ntp/drift or something like 
that.  With a good local clock (gps, pps), you can easily track temperature.  
(I'll say more if anybody wants.)


Historical trivia:

I first learned about this back in 1976 or early 1977.  Shortly after I got 
to Xerox, Ed Taft fixed a bug in the Alto OS by adding that code.  The 
machine was designed with a 170 ns cycle time.  Everybody knew that, 
including the guys who wrote the timekeeping code.

You can't buy 170ns crystals.  They come in MHz.  So they got 5.88 MHz.  If I 
did the math right, that's off by 340 pm or 29 seconds per day.  (That feels 
about right.  30 seconds per day is horrible for a mature system, but close 
enough that many other things will be more important during the early 
days/years of a project.)

More trivia: The early 3 megabit Ethernet was actually 5.88 / 2.



-- 
These are my opinions, not necessarily my employer's.  I hate spam.






More information about the time-nuts mailing list