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.