William Unruh wrote:
Now you could have the computer run in TAI and then do the translation
in userland software. But of course since most things expect utc
seconds, every call to the clock would require you figuring out what the
offset from utc to tai is, and subtract that number, making time system calls
much slower.

I used to think this was true, but in reality it isn't:

By _far_ the largest majority of all system time calls are asking for the _current_ time, right?

This time is already interpolated, using something like the RDTSC counter to estimate the offset from the last hardware tick when the baseline clock register/location was updated, so we are talking about something like 20-50 clock cycles:

Adding one more instruction to this code which simply subtracts the current offset between TAI and UTC would normally cost a single additional cycle, if we also add some guard code to detect the case where we were currently inside a leap second this would add a single branch which for all practical purposes would be perfectly predicted:

First we get the interpolated clock value in TAI + ns:

  clock = os_clock_value; //  ( Assume TAI sec plus ns storage)
  tdelta = (uint32_t) ((rdtsc - os_clock_tsc) * nanoseconds_per_tsc);
  tdelta += clock.nano;
  if (tdelta >= 1000000000) {
    clock.tai++;
    tdelta -= 1000000000;
  }
  clock.nano = tdelta;

converting to UTC is trivial (the OS makes sure that the offset value is correct):

  clock.utc = clock.tai - tai_utc_offset;

then we add code to check for a leap second in progress:

  if (clock.tai == current_leap_second) {
    // Here we effectively stop the UTC clock, just incrementing
    // the ns value once per call
    clock.ns = os_clock_ns++;
  }

Library calls to convert TAI times in the past to/from YMDHMS will of course require some more code, and questions about future times _will_ be wrong, so you have to store future timestamps in the format which is most applicable. I.e. a future meeting assignment should be stored in YMDHMS-ZONE format, while a time at a given numer of seconds from now needs to be stored in TAI.

I suspect that you can write pretty fast code to handle the TAI<->UTC conversions without needing any huge tables, just the list of leap seconds up to now:

Trivial code would simply scan the table, possibly from the current end since recent timestamps are more common than old, or you could use some form of table lookup, i.e. make a table that contains the delta count for each possible insertion point:

Take the UTC value, subtract 1972-04-01 then divide by the average number of seconds in half a year: This gives a small integer, currently in the 0 to 85 range, which is used to lookup a byte indexing the closest relevant leap second.

Comparing against this value controls which tai-utc offset count to use.

Anyway, it looks doable in 20+ clock cycles if it is a heavily used function (otherwise the timing doesn't matter) so that the lookup tables are cached.

Terje

--
- <Terje.Mathisen at tmsw.no>
"almost all programming can be viewed as an exercise in caching"

_______________________________________________
questions mailing list
questions@lists.ntp.org
http://lists.ntp.org/listinfo/questions

Reply via email to