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 mWd/Run ---------------------------- ---------- --------- Time.now 37.93ns 2.00w Time_ns.now 28.18ns TSC.Calibrator.calibrate 115.43ns 28.00w TSC.now 7.14ns TSC.to_time 3.44ns 2.00w TSC.to_time (TSC.now ()) 8.24ns 2.00w TSC.to_time_ns 14.20ns TSC.to_time_ns(TSC.now ()) 9.80ns id 2.91ns TSC.Span.of_ns 5.81ns TSC.Span.to_ns 3.70ns
(* CR-someday cfalls: Maybe a word about the semantics of t
would be useful. For
example, does it make sense to send a sexp of t
from one box to another, and then
convert it to a Time.t
? The answer would be "no" if t
is a count of the cycles
since this process was started, or something like that. Is that what it is? *)
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
Span
indicates some integer number of cycles.
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.