diff options
author | Dave Barach <dave@barachs.net> | 2020-01-31 15:38:28 -0500 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2020-01-31 21:56:12 +0000 |
commit | 78a1877463e59c15d0554bab61b5ad803625834f (patch) | |
tree | 4b8f206dc7b11a12ad261ea2fce8c3a63107656e /docs/gettingstarted/developers | |
parent | 36a0c4d65c50a63b57f6d217711bc2f6af931401 (diff) |
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
Diffstat (limited to 'docs/gettingstarted/developers')
-rw-r--r-- | docs/gettingstarted/developers/infrastructure.md | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/docs/gettingstarted/developers/infrastructure.md b/docs/gettingstarted/developers/infrastructure.md index 2c798f4a337..12f96d5ad41 100644 --- a/docs/gettingstarted/developers/infrastructure.md +++ b/docs/gettingstarted/developers/infrastructure.md @@ -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 ------ |