Up

module Time_stamp_counter

: sig

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:

See also: http://en.wikipedia.org/wiki/Time_Stamp_Counter

#
type t = private Core_kernel.Std.Int63.t
#
module Calibrator : sig
#
type t
#
val create : unit -> t

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.

#
val calibrate : ?t:t -> unit -> unit

calibrate ~t updates t by measuring the current value of the TSC and Time.now.

#
val cpu_mhz : (?t:t -> unit -> float) Core_kernel.Std.Or_error.t

Returns the estimated MHz of the CPU's time-stamp-counter based on the TSC and Time.now (). This function is undefined on 32bit machines.

#
val t_of_sexp : Sexplib.Sexp.t -> t
#
val sexp_of_t : t -> Sexplib.Sexp.t
#
val bin_t : t Core_kernel.Std.Bin_prot.Type_class.t
#
val bin_read_t : t Core_kernel.Std.Bin_prot.Read.reader
#
val __bin_read_t__ : (int -> t) Core_kernel.Std.Bin_prot.Read.reader
#
val bin_reader_t : t Core_kernel.Std.Bin_prot.Type_class.reader
#
val bin_size_t : t Core_kernel.Std.Bin_prot.Size.sizer
#
val bin_write_t : t Core_kernel.Std.Bin_prot.Write.writer
#
val bin_writer_t : t Core_kernel.Std.Bin_prot.Type_class.writer
end
#
module Span : sig

Span indicates some integer number of cycles.

#
type t = private Core_kernel.Std.Int63.t
include Core_kernel.Std.Comparable with type t := t
include Core_kernel.Std.Intable with type t := t
#
val (+) : t -> t -> t
#
val (-) : t -> t -> t
#
val to_time_span : ?calibrator:Calibrator.t -> t -> Time.Span.t
#
val to_ns : ?calibrator:Calibrator.t -> t -> Core_kernel.Std.Int63.t
#
val of_ns : ?calibrator:Calibrator.t -> Core_kernel.Std.Int63.t -> t
#
val t_of_sexp : Sexplib.Sexp.t -> t
#
val sexp_of_t : t -> Sexplib.Sexp.t
#
val bin_t : t Core_kernel.Std.Bin_prot.Type_class.t
#
val bin_read_t : t Core_kernel.Std.Bin_prot.Read.reader
#
val __bin_read_t__ : (int -> t) Core_kernel.Std.Bin_prot.Read.reader
#
val bin_reader_t : t Core_kernel.Std.Bin_prot.Type_class.reader
#
val bin_size_t : t Core_kernel.Std.Bin_prot.Size.sizer
#
val bin_write_t : t Core_kernel.Std.Bin_prot.Write.writer
#
val bin_writer_t : t Core_kernel.Std.Bin_prot.Type_class.writer
end
#
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 -> Time_ns.t

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

#
val t_of_sexp : Sexplib.Sexp.t -> t
#
val sexp_of_t : t -> Sexplib.Sexp.t
#
val compare : t -> t -> int
#
val bin_t : t Core_kernel.Std.Bin_prot.Type_class.t
#
val bin_read_t : t Core_kernel.Std.Bin_prot.Read.reader
#
val __bin_read_t__ : (int -> t) Core_kernel.Std.Bin_prot.Read.reader
#
val bin_reader_t : t Core_kernel.Std.Bin_prot.Type_class.reader
#
val bin_size_t : t Core_kernel.Std.Bin_prot.Size.sizer
#
val bin_write_t : t Core_kernel.Std.Bin_prot.Write.writer
#
val bin_writer_t : t Core_kernel.Std.Bin_prot.Type_class.writer
end