vppinfra: write up clib_time_t

Describe the clock rate adjustment algorithm in detail

Type: docs

Signed-off-by: Dave Barach <dave@barachs.net>
Change-Id: I5bcab18efafe05cd1db9a4b01ce6a6ba66e383fa
This commit is contained in:
Dave Barach
2020-01-31 15:38:28 -05:00
committed by Dave Barach
parent 36a0c4d65c
commit 78a1877463

View File

@ -114,6 +114,63 @@ key\_pointer. It is usually a bad mistake to pass the address of a
vector element as the second argument to hash\_set\_mem. It is perfectly
fine to memorize constant string addresses in the text segment.
Timekeeping
-----------
Vppinfra includes high-precision, low-cost timing services. The
datatype clib_time_t and associated functions reside in
./src/vppinfra/time.\[ch\]. Call clib_time_init (clib_time_t \*cp) to
initialize the clib_time_t object.
Clib_time_init(...) can use a variety of different ways to establish
the hardware clock frequency. At the end of the day, vppinfra
timekeeping takes the attitude that the operating system's clock is
the closest thing to a gold standard it has handy.
When properly configured, NTP maintains kernel clock synchronization
with a highly accurate off-premises reference clock. Notwithstanding
network propagation delays, a synchronized NTP client will keep the
kernel clock accurate to within 50ms or so.
Why should one care? Simply put, oscillators used to generate CPU
ticks aren't super accurate. They work pretty well, but a 0.1% error
wouldn't be out of the question. That's a minute and a half's worth of
error in 1 day. The error changes constantly, due to temperature
variation, and a host of other physical factors.
It's far too expensive to use system calls for timing, so we're left
with the problem of continously adjusting our view of the CPU tick
register's clocks_per_second parameter.
The clock rate adjustment algorithm measures the number of cpu ticks
and the "gold standard" reference time across an interval of
approximately 16 seconds. We calculate clocks_per_second for the
interval: use rdtsc (on x86_64) and a system call to get the latest
cpu tick count and the kernel's latest nanosecond timestamp. We
subtract the previous interval end values, and use exponential
smoothing to merge the new clock rate sample into the clocks_per_second
parameter.
As of this writing, we maintain the clock rate by way of the following
first-order differential equation:
```
clocks_per_second(t) = clocks_per_second(t-1) * K + sample_cps(t)*(1-K)
where K = e**(-1.0/3.75);
```
This yields a per observation "half-life" of 1 minute. Empirically,
the clock rate converges within 5 minutes, and appears to maintain
near-perfect agreement with the kernel clock in the face of ongoing
NTP time adjustments.
See ./src/vppinfra/time.c:clib_time_verify_frequency(...) to look at
the rate adjustment algorithm. The code rejects frequency samples
corresponding to the sort of adjustment which might occur if someone
changes the gold standard kernel clock by several seconds.
Format
------