[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

time of day to greater than one second accuracy



    Date: Sun, 25 Mar 90 20:51:06 PST
    From: lakin@csli.Stanford.EDU (Fred Lakin)

    For a reaction-time experiment, i need to record time of day down to
    hundredth-seconds. What I need is not merely elapsed hundredth-seconds
    during the experiment, but a hundredth-second accuracy version of
    (lisp:get-decoded-time). It would return values like:

       48.88 53 18 25 3 1990
	 ;s  m  h  d  m  y

I needed something like this at one point about a year ago, and
this is a precis of what I did:

(defstruct (trace-table (:conc-name tt-) ...)
  ...
  internal-initialization-time			;For calibration
  universal-initialization-time
  ...)

(defun-in-flavor (make-trace-table trace-table-mixin) ()
  (let ((new-tt ...))
    (setf ... 
	  (tt-universal-initialization-time new-tt) (get-universal-time)
	  (tt-internal-initialization-time new-tt) (get-internal-real-time)
	  ...)
    ...
    new-trace-table))

So much so good.  Now, without loss of generality, you can just
assume that your first reading is exactly at ss.00, and subtract
your INTERNAL-INITIALIZATION-TIME from every internal time you
write down, divide the result by INTERNAL-TIME-UNITS-PER-SECOND,
and add the UNIVERSAL-INITIALIZATION-TIME to the result:

  (multiple-value-bind (seconds fraction)
      (floor (- (te-time trace-entry) (tt-internal-initialization-time tt))
	     internal-time-units-per-second)
    (multiple-value-bind (sec min hr day month year)
	(decode-universal-time (+ seconds (tt-universal-initialization-time tt)))
      (values (+ sec (/ fraction internal-time-units-per-second))
	      min hr day month year)))

Of course, for efficiency you may choose not to call DECODE-UNIVERSAL-TIME
each time through the loop.

[Warning: non-portable efficiency hack follows:]

I found that calling GET-INTERNAL-REAL-TIME was costing too much
for my needs, and wrote a version which did what I needed and
cost 20 microseconds less per call:

  (defmacro-in-flavor (get-internal-real-time trace-table-mixin) () 
    '(lsh (sys:%microsecond-clock) -10))

[I was writing only 21 or so bits of time data into my trace
entries, so it didn't matter that this only gives 22 bits of
accuracy on the 36xx family.]