Should GET-INTERNAL-REALTIME be monotonous?

Max Rottenkolber max at mr.gy
Fri Jul 14 13:41:49 UTC 2017


Hello implementation hackers, :-)

I have looked at a bunch of CL implementations (CCL, ECL, SBCL) and noticed
that they implement GET-INTERNAL-REALTIME to be non-monotonous (i.e. affected
by system time). I would have expected it be a monotonic time source in
contrast to GET-UNIVERSAL-TIME.

While the standard is not particularly clear about this[1], it seems to me
that it at least intends to enable implementations to provide such a time
source. Furthermore, I have seen and picked up the pattern following to measure
the run-time of programs, i.e. write benchmarks

  (let ((start (get-internal-real-time)))
    ;; do <stuff>
    (/ (- (get-internal-real-time) start) internal-time-units-per-second))

and expect it to return the time elapsed while doing <stuff>, consistently.
Needless to say, if GET-INTERNAL-REALTIME is non-monotonous the results of this
pattern are inconsistent.

My conclusion is that, generally speaking, hackers would benefit from
GET-INTERNAL-REALTIME being monotonic. More specifically, it would be
especially beneficial if the pattern described would be de-facto portable, i.e.
if all implementations implemented GET-INTERNAL-REALTIME as being monotonic.

Looking at the implementation side, the question arises whether its worth the
implementation cost, which mostly consists of chasing down the OS calls to
achieve this on the various platforms (and test it). There is an existing
project “monotonic-clock” that attempts to bring monotonic clocks to CL using
CFFI:

  https://github.com/death/monotonic-clock

We have started to gather the monotonic clock incantations for various OSes
there. I view this as the most cost-effective solution to this issue, as it
takes the burden of implementers by presenting a portable, centralized library.

On the other hand, I still view a monotonic clock as a fundamental feature of a
language runtime (many, if not the majority of applications, need to measure
their performance for regressions). Another plus I see, is that a coordinated
move by implementers would make existing code that uses the described pattern
more correct, without having to rewrite that code using the monotonic-clock
library (this also includes existing code that expects GET-INTERNAL-REALTIME to
be monotonic for other purposes, i.e. timeouts, intervals, ...).

(Of course its easy to say, “its the code’s fault for being wrong”, but hey,
what do you expect if you call GET-INTERNAL-***REAL***-TIME? Oh, -3.6 seconds
have elapsed? How very real!)

(Also: TIME has to be implemented using *some* monotonic time source, why not
use a monotonic GET-INTERNAL-REALTIME?)

Furthermore, given a central collection of these incantations would make it
easy for implementers to reuse them for the implementation of
GET-INTERNAL-REALTIME (this mostly involves converting the CFFI calls to
implementation specific FFI layers).

I see three ways forward, ordered by cost of effort:

  1 (free) - implementations do nothing, point to monotonic-clock

  2 (somewhat costly) - implementations “fix” GET-INTERNAL-REALTIME via
  informal coordination

  3 (involved) - we get a CDR on the way to formally define an extension that
  guarantees GET-INTERNAL-REALTIME to be monotonic


I would obviously pick two or three. I would volunteer to do the required
implementation work for CCL, and submit a CDR if there is a consensus for that.

But your mileage my differ, what do you think?

Cheers,
Max


1: get-internal-real-time (Function)

Syntax:

— Function: get-internal-real-time <no arguments> → internal-time

Arguments and Values:

internal-time—a non-negative integer.

Description:

get-internal-real-time returns as an integer the current time in internal time
units, relative to an arbitrary time base. The difference between the values of
two calls to this function is the amount of elapsed real time (i.e., clock
time) between the two calls.

Affected By:

Time of day (i.e., the passage of time). The time base affects the result
magnitude.

See Also:

internal-time-units-per-second




More information about the implementation-hackers mailing list