High-performance timing.
This module provides the fast function now () which is our best effort
high-performance cycle counter for a given platform. For x86 systems this retrieves
the CPU's internal time stamp counter using the RDTSC instruction. For systems that
do not have a RDTSC instruction, we fallback to using
clock_gettime(CLOCK_MONOTONIC).
Here is a benchmark of execution time in nanos and allocations in words:
Name Time/Run Minor
------------------------------- ---------- -------
Time.now 39.02 2.00
TSC.now 7.54
TSC.to_time 4.88 2.00
TSC.to_time (TSC.now ()) 8.54 2.00
TSC.to_time_nanos 4.49
TSC.to_time_nanos(TSC.now ()) 8.95
Calibrator.calibrate 279 34.00
Type t is an Int63.t and consequently has no allocation overhead (on 64-bit
machines), unlike Time.now () which returns a boxed float.
Functions are also provided to estimate the relationship of CPU time-stamp-counter
frequency to real time, thereby allowing one to convert from t to Time.t. There
are some caveats to this that are worth noting:
Time.t depends on an estimate of the time-stamp-counter
frequency. This frequency may be volatile on some systems, thereby reducing the
utility of this conversion. See the Calibrator module below for details.t can only be converted to a Time.t if one also has a
recently calibrated Calibrator.t from the same machine.See also: http://en.wikipedia.org/wiki/Time_Stamp_Counter
create () creates an uninitialized calibrator instance. Creating a calibrator
takes about 3ms. One needs a recently calibrated Calibrator.t and the TSC value
from the same machine to meaningfully convert the TSC value to a Time.t.
calibrate ~t updates t by measuring the current value of the TSC and
Time.now.
to_time t converts a t to a Time.t. It is guaranteed that repeated calls
of to_time () will return nondecreasing Time.t values.