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.