Up

Module Time_stamp_counter

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:

  • The conversion to 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.
  • The captured 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

Signature

type t = private Core_kernel.Std.Int63.t
val t_of_sexp : Sexplib.Sexp.t -> t
val sexp_of_t : t -> Sexplib.Sexp.t
val compare : t -> t -> int
val __bin_read_t__ : (int -> t) Core_kernel.Std.Bin_prot.Read.reader
module Calibrator : sig .. end
A calibrator contains a snapshot of machine-specific information that is used to convert between TSC values and clock time.
module Span : sig .. end
Span indicates some integer number of cycles.
external now : unit -> t = "tsc_get" "noalloc"
val diff : t -> t -> Span.t
val add : t -> Span.t -> t
val to_int63 : t -> Core_kernel.Std.Int63.t

to_int63 t returns the TSC value represented by t as an Int63.t.

val to_time : ?calibrator:Calibrator.t -> t -> Time.t

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.

val to_time_ns : ?calibrator:Calibrator.t -> t -> Core_kernel.Std.Time_ns.t

to_time_ns t converts a t to an integer number of nanos since the epoch.