2012-03-26 19:12:03 -04:00
|
|
|
|
PEP: 418
|
2012-04-12 07:38:06 -04:00
|
|
|
|
Title: Add monotonic time, performance counter and process time functions
|
2012-03-26 19:12:03 -04:00
|
|
|
|
Version: $Revision$
|
|
|
|
|
Last-Modified: $Date$
|
2012-04-11 19:06:31 -04:00
|
|
|
|
Author: Jim Jewett <jimjjewett@gmail.com>, Victor Stinner <victor.stinner@gmail.com>
|
2012-03-26 19:12:03 -04:00
|
|
|
|
Status: Draft
|
|
|
|
|
Type: Standards Track
|
|
|
|
|
Content-Type: text/x-rst
|
|
|
|
|
Created: 26-March-2012
|
|
|
|
|
Python-Version: 3.3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Abstract
|
|
|
|
|
========
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
This PEP proposes to add ``time.get_clock_info(name)``,
|
|
|
|
|
``time.monotonic()``, ``time.perf_counter()`` and
|
|
|
|
|
``time.process_time()`` functions to Python 3.3.
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rationale
|
|
|
|
|
=========
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
If a program uses the system clock to schedule events or to implement
|
|
|
|
|
a timeout, it will not run events at the right moment or stop the
|
|
|
|
|
timeout too early or too late when the system clock is set manually or
|
|
|
|
|
adjusted automatically by NTP. A monotonic clock should be used
|
|
|
|
|
instead to not be affected by system clock updates.
|
|
|
|
|
|
|
|
|
|
To measure the performance of a function, ``time.clock()`` can be used
|
|
|
|
|
but it is very different on Windows and on Unix. On Windows,
|
|
|
|
|
``time.clock()`` includes time elapsed during sleep, whereas it does
|
|
|
|
|
not on Unix. ``time.clock()`` precision is very good on Windows, but
|
|
|
|
|
very bad on Unix. The new ``time.perf_counter()`` function can be
|
|
|
|
|
used instead to always get the most precise performance counter with a
|
2012-04-12 07:38:06 -04:00
|
|
|
|
portable behaviour.
|
2012-04-10 19:37:04 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
To measure CPU time, Python does not provide directly a portable
|
|
|
|
|
function. ``time.clock()`` can be used on Unix, but it has a bad
|
|
|
|
|
precision. ``resource.getrusage()`` can also be used on Unix, but it
|
|
|
|
|
requires to get fields of a structure and compute the sum of time
|
|
|
|
|
spent in kernel space and user space. The new ``time.process_time()``
|
|
|
|
|
function acts as a portable counter that always measures CPU time
|
|
|
|
|
(doesn't include time elapsed during sleep) and has the best available
|
2012-04-12 07:38:06 -04:00
|
|
|
|
precision.
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Each operating system implements clocks and performance counters
|
|
|
|
|
differently, and it is useful to know exactly which function is used
|
|
|
|
|
and some properties of the clock like its resolution and its
|
|
|
|
|
precision. The new ``time.get_clock_info()`` function gives access to
|
|
|
|
|
all available information of each Python time function.
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-12 07:38:06 -04:00
|
|
|
|
New functions:
|
2012-03-26 19:30:38 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* ``time.monotonic()``: timeout and scheduling, not affected by system
|
|
|
|
|
clock updates
|
|
|
|
|
* ``time.perf_counter()``: benchmarking, most precise clock for short
|
|
|
|
|
period
|
|
|
|
|
* ``time.process_time()``: profiling, CPU time of the process
|
2012-03-31 02:53:07 -04:00
|
|
|
|
|
2012-04-13 16:07:36 -04:00
|
|
|
|
Users of new functions:
|
|
|
|
|
|
|
|
|
|
* time.monotonic(): concurrent.futures, multiprocessing, queue, subprocess,
|
|
|
|
|
telnet and threading modules to implement timeout
|
|
|
|
|
* time.perf_counter(): trace and timeit modules, pybench program
|
|
|
|
|
* time.process_time(): profile module
|
|
|
|
|
* time.get_clock_info(): pybench program to display information about the
|
|
|
|
|
timer like the precision or the resolution
|
|
|
|
|
|
|
|
|
|
The ``time.clock()`` function is deprecated by this PEP because it is not
|
|
|
|
|
portable: it behaves differently depending on the operating system.
|
|
|
|
|
``time.perf_counter()`` or ``time.process_time()`` should be used instead,
|
|
|
|
|
depending on your requirements. ``time.clock()`` is marked as deprecated but
|
|
|
|
|
is not planned for removal.
|
2012-03-30 18:50:05 -04:00
|
|
|
|
|
|
|
|
|
|
2012-04-12 07:38:06 -04:00
|
|
|
|
Python functions
|
|
|
|
|
================
|
2012-03-26 19:30:38 -04:00
|
|
|
|
|
2012-04-12 07:38:06 -04:00
|
|
|
|
New functions
|
|
|
|
|
-------------
|
2012-03-27 13:27:28 -04:00
|
|
|
|
|
2012-04-12 07:38:06 -04:00
|
|
|
|
time.get_clock_info(name)
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
2012-03-27 13:27:28 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Get information on the specified clock. Supported clocks:
|
2012-03-27 13:34:04 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* "clock": time.clock()
|
|
|
|
|
* "monotonic": time.monotonic()
|
|
|
|
|
* "perf_counter": time.perf_counter()
|
|
|
|
|
* "process_time": time.process_time()
|
|
|
|
|
* "time": time.time()
|
2012-04-12 07:38:06 -04:00
|
|
|
|
|
|
|
|
|
Return a dictionary with the following keys:
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* Mandatory keys:
|
2012-04-12 07:38:06 -04:00
|
|
|
|
|
2012-04-13 16:07:36 -04:00
|
|
|
|
* "implementation" (str): name of the underlying operating system
|
2012-04-12 13:12:48 -04:00
|
|
|
|
function. Examples: "QueryPerformanceCounter()",
|
|
|
|
|
"clock_gettime(CLOCK_REALTIME)".
|
|
|
|
|
* "resolution" (float): resolution in seconds of the clock
|
|
|
|
|
* "is_monotonic" (bool): True if the clock cannot go backward
|
2012-04-12 07:38:06 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* Optional keys:
|
2012-04-12 07:38:06 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* "precision" (float): precision in seconds of the clock
|
|
|
|
|
* "is_adjusted" (bool): True if the clock can be adjusted (e.g. by a
|
|
|
|
|
NTP daemon)
|
2012-03-27 13:34:04 -04:00
|
|
|
|
|
2012-03-27 13:27:28 -04:00
|
|
|
|
|
2012-04-03 20:57:55 -04:00
|
|
|
|
time.monotonic()
|
2012-04-12 07:38:06 -04:00
|
|
|
|
^^^^^^^^^^^^^^^^
|
2012-03-27 20:18:11 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Monotonic clock, cannot go backward. It is not affected by system
|
|
|
|
|
clock updates. The reference point of the returned value is
|
|
|
|
|
undefined, so that only the difference between the results of
|
|
|
|
|
consecutive calls is valid.
|
2012-03-27 13:27:28 -04:00
|
|
|
|
|
2012-04-13 16:07:36 -04:00
|
|
|
|
Availability: Windows, Mac OS X, Unix, Solaris. Not available on GNU/Hurd.
|
2012-04-03 20:57:55 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
Pseudo-code [#pseudo]_::
|
2012-03-27 13:27:28 -04:00
|
|
|
|
|
|
|
|
|
if os.name == 'nt':
|
2012-03-27 19:57:37 -04:00
|
|
|
|
# GetTickCount64() requires Windows Vista, Server 2008 or later
|
2012-03-27 13:27:28 -04:00
|
|
|
|
if hasattr(time, '_GetTickCount64'):
|
2012-04-03 20:57:55 -04:00
|
|
|
|
def monotonic():
|
2012-04-02 19:45:49 -04:00
|
|
|
|
return _time.GetTickCount64() * 1e-3
|
2012-03-27 13:27:28 -04:00
|
|
|
|
else:
|
2012-04-03 20:57:55 -04:00
|
|
|
|
def monotonic():
|
2012-03-27 13:27:28 -04:00
|
|
|
|
ticks = _time.GetTickCount()
|
2012-04-03 20:57:55 -04:00
|
|
|
|
if ticks < monotonic.last:
|
2012-03-27 13:27:28 -04:00
|
|
|
|
# Integer overflow detected
|
2012-04-03 20:57:55 -04:00
|
|
|
|
monotonic.delta += 2**32
|
|
|
|
|
monotonic.last = ticks
|
|
|
|
|
return (ticks + monotonic.delta) * 1e-3
|
|
|
|
|
monotonic.last = 0
|
|
|
|
|
monotonic.delta = 0
|
2012-03-27 19:45:51 -04:00
|
|
|
|
|
|
|
|
|
elif os.name == 'mac':
|
2012-04-03 20:57:55 -04:00
|
|
|
|
def monotonic():
|
|
|
|
|
if monotonic.factor is None:
|
2012-03-27 13:27:28 -04:00
|
|
|
|
factor = _time.mach_timebase_info()
|
2012-04-03 20:57:55 -04:00
|
|
|
|
monotonic.factor = timebase[0] / timebase[1]
|
|
|
|
|
return _time.mach_absolute_time() * monotonic.factor
|
|
|
|
|
monotonic.factor = None
|
2012-03-27 19:45:51 -04:00
|
|
|
|
|
2012-04-03 20:57:55 -04:00
|
|
|
|
elif hasattr(time, "clock_gettime"):
|
|
|
|
|
def monotonic():
|
|
|
|
|
if monotonic.use_clock_highres:
|
2012-03-28 09:02:58 -04:00
|
|
|
|
try:
|
|
|
|
|
time.clock_gettime(time.CLOCK_HIGHRES)
|
|
|
|
|
except OSError:
|
2012-04-03 20:57:55 -04:00
|
|
|
|
monotonic.use_clock_highres = False
|
|
|
|
|
return time.clock_gettime(time.CLOCK_MONOTONIC)
|
|
|
|
|
monotonic.use_clock_highres = (hasattr(time, 'clock_gettime')
|
2012-03-28 09:02:58 -04:00
|
|
|
|
and hasattr(time, 'CLOCK_HIGHRES'))
|
2012-03-30 18:50:05 -04:00
|
|
|
|
|
2012-03-30 20:00:43 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
On Windows, ``QueryPerformanceCounter()`` is not used even though it
|
|
|
|
|
has a better precision than ``GetTickCount()``. It is not reliable
|
|
|
|
|
and has too many issues.
|
2012-03-28 09:02:58 -04:00
|
|
|
|
|
2012-04-13 20:08:16 -04:00
|
|
|
|
``time.monotonic()`` detects ``GetTickCount()`` integer overflow (32 bits,
|
|
|
|
|
roll-over after 49.7 days): it increases a delta by 2\ :sup:`32` each time
|
|
|
|
|
than an overflow is detected. The delta is stored in the process-local
|
|
|
|
|
state and so the value of ``time.monotonic()`` may be different in two
|
|
|
|
|
Python processes running for more than 49 days.
|
2012-03-27 13:27:28 -04:00
|
|
|
|
|
2012-03-26 19:30:38 -04:00
|
|
|
|
|
2012-04-12 07:38:06 -04:00
|
|
|
|
time.perf_counter()
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Performance counter used for benchmarking. It is monotonic,
|
|
|
|
|
i.e. cannot go backward. It does include time elapsed during sleep.
|
|
|
|
|
The reference point of the returned value is undefined, so that only
|
|
|
|
|
the difference between the results of consecutive calls is valid and
|
|
|
|
|
is number of seconds.
|
2012-04-12 07:38:06 -04:00
|
|
|
|
|
|
|
|
|
Pseudo-code::
|
|
|
|
|
|
|
|
|
|
def perf_counter():
|
|
|
|
|
if perf_counter.use_performance_counter:
|
|
|
|
|
if perf_counter.perf_frequency is None:
|
|
|
|
|
try:
|
|
|
|
|
perf_counter.perf_frequency = float(_time.QueryPerformanceFrequency())
|
|
|
|
|
except OSError:
|
|
|
|
|
# QueryPerformanceFrequency() fails if the installed
|
|
|
|
|
# hardware does not support a high-resolution performance
|
|
|
|
|
# counter
|
|
|
|
|
perf_counter.use_performance_counter = False
|
|
|
|
|
else:
|
|
|
|
|
return _time.QueryPerformanceCounter() / perf_counter.perf_frequency
|
|
|
|
|
else:
|
|
|
|
|
return _time.QueryPerformanceCounter() / perf_counter.perf_frequency
|
|
|
|
|
if perf_counter.use_monotonic:
|
|
|
|
|
# Monotonic clock is preferred over system clock
|
|
|
|
|
try:
|
|
|
|
|
return time.monotonic()
|
|
|
|
|
except OSError:
|
|
|
|
|
perf_counter.use_monotonic = False
|
|
|
|
|
return time.time()
|
|
|
|
|
perf_counter.use_performance_counter = (os.name == 'nt')
|
|
|
|
|
if perf_counter.use_performance_counter:
|
|
|
|
|
perf_counter.perf_frequency = None
|
|
|
|
|
perf_counter.use_monotonic = hasattr(time, 'monotonic')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
time.process_time()
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
2012-04-12 16:42:54 -04:00
|
|
|
|
Process time used for profiling: sum of the kernel and user-space CPU
|
2012-04-12 13:12:48 -04:00
|
|
|
|
time. It does not include time elapsed during sleep. The reference
|
|
|
|
|
point of the returned value is undefined, so that only the difference
|
|
|
|
|
between the results of consecutive calls is valid.
|
2012-04-12 07:38:06 -04:00
|
|
|
|
|
2012-04-12 19:21:00 -04:00
|
|
|
|
Pseudo-code [#pseudo]_::
|
2012-04-12 07:38:06 -04:00
|
|
|
|
|
|
|
|
|
if os.name == 'nt':
|
|
|
|
|
def process_time():
|
|
|
|
|
handle = win32process.GetCurrentProcess()
|
|
|
|
|
process_times = win32process.GetProcessTimes(handle)
|
|
|
|
|
return (process_times['UserTime'] + process_times['KernelTime']) * 1e-7
|
|
|
|
|
else:
|
2012-04-13 08:04:37 -04:00
|
|
|
|
import os
|
|
|
|
|
try:
|
|
|
|
|
import resource
|
|
|
|
|
except ImportError:
|
|
|
|
|
has_resource = False
|
|
|
|
|
else:
|
|
|
|
|
has_resource = True
|
|
|
|
|
|
2012-04-12 19:21:00 -04:00
|
|
|
|
def process_time():
|
|
|
|
|
if process_time.use_process_cputime:
|
|
|
|
|
try:
|
|
|
|
|
return time.clock_gettime(time.CLOCK_PROCESS_CPUTIME_ID)
|
|
|
|
|
except OSError:
|
|
|
|
|
process_time.use_process_cputime = False
|
|
|
|
|
if process_time.use_getrusage:
|
2012-04-13 08:04:37 -04:00
|
|
|
|
try:
|
|
|
|
|
usage = resource.getrusage(resource.RUSAGE_SELF)
|
|
|
|
|
return usage[0] + usage[1]
|
|
|
|
|
except OSError:
|
|
|
|
|
process_time.use_getrusage = False
|
|
|
|
|
if process_time.use_times:
|
|
|
|
|
try:
|
|
|
|
|
times = os.times()
|
|
|
|
|
return times[0] + times[1]
|
|
|
|
|
except OSError:
|
|
|
|
|
process_time.use_getrusage = False
|
2012-04-12 19:21:00 -04:00
|
|
|
|
return _time.clock()
|
|
|
|
|
process_time.use_process_cputime = (
|
|
|
|
|
hasattr(time, 'clock_gettime')
|
|
|
|
|
and hasattr(time, 'CLOCK_PROCESS_CPUTIME_ID'))
|
2012-04-13 08:04:37 -04:00
|
|
|
|
process_time.use_getrusage = has_resource
|
|
|
|
|
# On OS/2, only the 5th field of os.times() is set, others are zeros
|
|
|
|
|
process_time.use_times = (hasattr(os, 'times') and os.name != 'os2')
|
2012-04-12 07:38:06 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Existing functions
|
|
|
|
|
------------------
|
|
|
|
|
|
|
|
|
|
time.time()
|
|
|
|
|
^^^^^^^^^^^
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
The system time is the "wall clock". It can be set manually by the
|
2012-04-12 07:38:06 -04:00
|
|
|
|
system administrator or automatically by a NTP daemon. It can jump
|
|
|
|
|
backward and forward. It is not monotonic.
|
|
|
|
|
|
|
|
|
|
It is available on all platforms and cannot fail.
|
|
|
|
|
|
|
|
|
|
Pseudo-code [#pseudo]_::
|
|
|
|
|
|
|
|
|
|
if os.name == "nt":
|
|
|
|
|
def time():
|
|
|
|
|
return _time.GetSystemTimeAsFileTime()
|
|
|
|
|
else:
|
|
|
|
|
def time():
|
|
|
|
|
if hasattr(time, "clock_gettime"):
|
|
|
|
|
try:
|
|
|
|
|
return time.clock_gettime(time.CLOCK_REALTIME)
|
|
|
|
|
except OSError:
|
|
|
|
|
# CLOCK_REALTIME is not supported (unlikely)
|
|
|
|
|
pass
|
|
|
|
|
if hasattr(_time, "gettimeofday"):
|
|
|
|
|
try:
|
|
|
|
|
return _time.gettimeofday()
|
|
|
|
|
except OSError:
|
|
|
|
|
# gettimeofday() should not fail
|
|
|
|
|
pass
|
|
|
|
|
if hasattr(_time, "ftime"):
|
|
|
|
|
return _time.ftime()
|
|
|
|
|
else:
|
|
|
|
|
return _time.time()
|
|
|
|
|
|
|
|
|
|
|
2012-04-08 19:32:02 -04:00
|
|
|
|
time.sleep()
|
2012-04-12 07:38:06 -04:00
|
|
|
|
^^^^^^^^^^^^
|
2012-04-08 19:32:02 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Suspend execution for the given number of seconds. The actual
|
|
|
|
|
suspension time may be less than that requested because any caught
|
|
|
|
|
signal will terminate the ``time.sleep()`` following execution of that
|
|
|
|
|
signal's catching routine. Also, the suspension time may be longer
|
|
|
|
|
than requested by an arbitrary amount because of the scheduling of
|
|
|
|
|
other activity in the system.
|
2012-04-08 19:32:02 -04:00
|
|
|
|
|
|
|
|
|
Pseudo-code [#pseudo]_::
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
import select
|
|
|
|
|
except ImportError:
|
|
|
|
|
has_select = False
|
|
|
|
|
else:
|
|
|
|
|
has_select = hasattr(select, "select")
|
|
|
|
|
|
|
|
|
|
if has_select:
|
|
|
|
|
def sleep(seconds):
|
|
|
|
|
return select.select([], [], [], seconds)
|
|
|
|
|
|
|
|
|
|
elif hasattr(_time, "delay"):
|
|
|
|
|
def sleep(seconds):
|
|
|
|
|
milliseconds = int(seconds * 1000)
|
|
|
|
|
_time.delay(milliseconds)
|
|
|
|
|
|
|
|
|
|
elif os.name == "nt":
|
|
|
|
|
def sleep(seconds):
|
|
|
|
|
milliseconds = int(seconds * 1000)
|
|
|
|
|
win32api.ResetEvent(hInterruptEvent);
|
|
|
|
|
win32api.WaitForSingleObject(sleep.sigint_event, milliseconds)
|
|
|
|
|
|
|
|
|
|
sleep.sigint_event = win32api.CreateEvent(NULL, TRUE, FALSE, FALSE)
|
|
|
|
|
# SetEvent(sleep.sigint_event) will be called by the signal handler of SIGINT
|
|
|
|
|
|
|
|
|
|
elif os.name == "os2":
|
|
|
|
|
def sleep(seconds):
|
|
|
|
|
milliseconds = int(seconds * 1000)
|
|
|
|
|
DosSleep(milliseconds)
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
def sleep(seconds):
|
|
|
|
|
seconds = int(seconds)
|
|
|
|
|
_time.sleep(seconds)
|
|
|
|
|
|
2012-04-12 07:38:06 -04:00
|
|
|
|
Deprecated functions
|
|
|
|
|
--------------------
|
2012-04-08 19:32:02 -04:00
|
|
|
|
|
2012-04-11 07:06:33 -04:00
|
|
|
|
time.clock()
|
2012-04-12 07:38:06 -04:00
|
|
|
|
^^^^^^^^^^^^
|
2012-04-11 07:06:33 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
On Unix, return the current processor time as a floating point number
|
|
|
|
|
expressed in seconds. The precision, and in fact the very definition
|
|
|
|
|
of the meaning of "processor time", depends on that of the C function
|
|
|
|
|
of the same name, but in any case, this is the function to use for
|
|
|
|
|
benchmarking Python or timing algorithms.
|
2012-04-11 07:06:33 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
On Windows, this function returns wall-clock seconds elapsed since the
|
|
|
|
|
first call to this function, as a floating point number, based on the
|
|
|
|
|
Win32 function ``QueryPerformanceCounter()``. The resolution is
|
|
|
|
|
typically better than one microsecond.
|
2012-04-11 07:06:33 -04:00
|
|
|
|
|
|
|
|
|
Pseudo-code [#pseudo]_::
|
|
|
|
|
|
|
|
|
|
if os.name == 'nt':
|
|
|
|
|
def clock():
|
|
|
|
|
if clock.use_performance_counter:
|
|
|
|
|
if clock.perf_frequency is None:
|
|
|
|
|
try:
|
|
|
|
|
clock.perf_frequency = float(_time.QueryPerformanceFrequency())
|
|
|
|
|
except OSError:
|
|
|
|
|
# QueryPerformanceFrequency() fails if the installed
|
|
|
|
|
# hardware does not support a high-resolution performance
|
|
|
|
|
# counter
|
|
|
|
|
clock.use_performance_counter = False
|
|
|
|
|
else:
|
|
|
|
|
return _time.QueryPerformanceCounter() / clock.perf_frequency
|
|
|
|
|
else:
|
|
|
|
|
return _time.QueryPerformanceCounter() / clock.perf_frequency
|
|
|
|
|
return _time.clock()
|
|
|
|
|
clock.use_performance_counter = True
|
|
|
|
|
clock.perf_frequency = None
|
|
|
|
|
else:
|
|
|
|
|
clock = _time.clock
|
|
|
|
|
|
|
|
|
|
|
2012-03-26 19:30:38 -04:00
|
|
|
|
|
2012-04-11 19:06:31 -04:00
|
|
|
|
Glossary
|
|
|
|
|
========
|
|
|
|
|
|
|
|
|
|
:Accuracy:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Is the answer correct? Any clock will eventually <drift>; if a
|
|
|
|
|
clock is intended to match <Civil Time>, it will need to be
|
2012-04-13 20:08:16 -04:00
|
|
|
|
<adjusted> back to the "true" time. See also `Accuracy and precision
|
|
|
|
|
<http://en.wikipedia.org/wiki/Accuracy_and_precision>`_.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Adjusted:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Resetting a clock to the correct time. This may be done either
|
|
|
|
|
with a <Step> or by <Slewing>.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Civil Time:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Time of day; external to the system. 10:45:13am is a Civil time;
|
|
|
|
|
45 seconds is not. Provided by existing function
|
|
|
|
|
``time.localtime()`` and ``time.gmtime()``. Not changed by this
|
|
|
|
|
PEP.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Clock:
|
|
|
|
|
An instrument for measuring time. Different clocks have different
|
2012-04-12 13:12:48 -04:00
|
|
|
|
characteristics; for example, a clock with <nanonsecond>
|
|
|
|
|
<precision> may start to <drift> after a few minutes, while a less
|
|
|
|
|
precise clock remained accurate for days. This PEP is primarily
|
|
|
|
|
concerned with clocks which use a unit of seconds.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Counter:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
A clock which increments each time a certain event occurs. A
|
|
|
|
|
counter is <strictly monotonic>, but not <clock_monotonic>. It can
|
|
|
|
|
be used to generate a unique (and ordered) timestamp, but these
|
|
|
|
|
timestamps cannot be mapped to <civil time>; tick creation may well
|
|
|
|
|
be bursty, with several advances in the same millisecond followed
|
|
|
|
|
by several days without any advance.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:CPU Time:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
A measure of how much CPU effort has been spent on a certain task.
|
|
|
|
|
CPU seconds are often normalized (so that a variable number can
|
|
|
|
|
occur in the same actual second). CPU seconds can be important
|
|
|
|
|
when profiling, but they do not map directly to user response time,
|
|
|
|
|
nor are they directly comparable to (real time) seconds.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Duration:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Elapsed time. The difference between the starting and ending
|
|
|
|
|
times. A defined <epoch> creates an implicit (and usually large)
|
|
|
|
|
duration. More precision can generally be provided for a
|
|
|
|
|
relatively small <duration>.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Drift:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
The accumulated error against "true" time, as defined externally to
|
|
|
|
|
the system.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Epoch:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
The reference point of a clock. For clocks providing <civil time>,
|
|
|
|
|
this is often midnight as the day (and year) rolled over to January
|
|
|
|
|
1, 1970. For a <clock_monotonic> clock, the epoch may be undefined
|
|
|
|
|
(represented as None).
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Latency:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Delay. By the time a clock call returns, the <real time> has
|
|
|
|
|
advanced, possibly by more than the precision of the clock.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Monotonic:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
The characteristics expected of a monotonic clock in practice.
|
|
|
|
|
Moving in at most one direction; for clocks, that direction is
|
|
|
|
|
forward. The <clock> should also be <steady>, and should be
|
|
|
|
|
convertible to a unit of seconds. The tradeoffs often include lack
|
|
|
|
|
of a defined <epoch> or mapping to <Civil Time>, and being more
|
|
|
|
|
expensive (in <latency>, power usage, or <duration> spent within
|
|
|
|
|
calls to the clock itself) to use. For example, the clock may
|
|
|
|
|
represent (a constant multiplied by) ticks of a specific quartz
|
|
|
|
|
timer on a specific CPU core, and calls would therefore require
|
|
|
|
|
synchronization between cores.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Precision:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Significant Digits. What is the smallest duration that the clock
|
|
|
|
|
can distinguish? This differs from <resolution> in that a
|
|
|
|
|
difference greater than the minimum precision is actually
|
|
|
|
|
meaningful.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Process Time:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Time elapsed since the process began. It is typically measured in
|
|
|
|
|
<CPU time> rather than <real time>, and typically does not advance
|
|
|
|
|
while the process is suspended.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Real Time:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Time in the real world. This differs from <Civil time> in that it
|
|
|
|
|
is not <adjusted>, but they should otherwise advance in lockstep.
|
|
|
|
|
It is not related to the "real time" of "Real Time [Operating]
|
|
|
|
|
Systems". It is sometimes called "wall clock time" to avoid that
|
|
|
|
|
ambiguity; unfortunately, that introduces different ambiguities.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Resolution:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Represented Digits. Note that many clocks will have a resolution
|
|
|
|
|
greater than their actual <precision>.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Slew:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
A slight change to a clock's speed, usually intended to correct
|
|
|
|
|
<drift> with respect to an external authority.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Stability:
|
|
|
|
|
Persistence of accuracy. A measure of expected <drift>.
|
|
|
|
|
|
|
|
|
|
:Steady:
|
|
|
|
|
A clock with high <stability> and relatively high <accuracy> and
|
2012-04-12 13:12:48 -04:00
|
|
|
|
<precision>. In practice, it is often used to indicate a
|
|
|
|
|
<clock_monotonic> clock, but places greater emphasis on the
|
|
|
|
|
consistency of the duration between subsequent ticks.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Step:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
An instantaneous change in the represented time. Instead of
|
|
|
|
|
speeding or slowing the clock (<slew>), a single offset is
|
|
|
|
|
permanently added.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:System Time:
|
|
|
|
|
Time as represented by the Operating System.
|
|
|
|
|
|
|
|
|
|
:Thread Time:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Time elapsed since the thread began. It is typically measured in
|
|
|
|
|
<CPU time> rather than <real time>, and typically does not advance
|
|
|
|
|
while the thread is idle.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
|
|
|
|
:Wallclock:
|
2012-04-12 13:12:48 -04:00
|
|
|
|
What the clock on the wall says. This is typically used as a
|
|
|
|
|
synonym for <real time>; unfortunately, wall time is itself
|
|
|
|
|
ambiguous.
|
2012-04-11 19:06:31 -04:00
|
|
|
|
|
2012-04-03 19:07:55 -04:00
|
|
|
|
|
2012-03-31 22:03:15 -04:00
|
|
|
|
Hardware clocks
|
|
|
|
|
===============
|
|
|
|
|
|
2012-04-11 19:22:23 -04:00
|
|
|
|
List of hardware clocks
|
|
|
|
|
-----------------------
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* HPET: An High Precision Event Timer (HPET) chip consists of a 64-bit
|
|
|
|
|
up-counter (main counter) counting at least at 10 MHz and a set of
|
|
|
|
|
up to 256 comparators (at least 3). Each HPET can have up to 32
|
|
|
|
|
timers. HPET can cause around 3 seconds of drift per day.
|
|
|
|
|
* TSC (Time Stamp Counter): Historically, the TSC increased with every
|
|
|
|
|
internal processor clock cycle, but now the rate is usually constant
|
|
|
|
|
(even if the processor changes frequency) and usually equals the
|
|
|
|
|
maximum processor frequency. Multiple cores having different TSC
|
|
|
|
|
values. Hibernation of system will reset TSC value. The RDTSC
|
|
|
|
|
instruction can be used to read this counter. CPU frequency scaling
|
|
|
|
|
for power saving.
|
|
|
|
|
* ACPI Power Management Timer: ACPI 24-bit timer with a frequency of
|
|
|
|
|
3.5 MHz (3,579,545 Hz).
|
2012-03-31 22:03:15 -04:00
|
|
|
|
* Cyclone: The Cyclone timer uses a 32-bit counter on IBM Extended
|
|
|
|
|
X-Architecture (EXA) chipsets which include computers that use the
|
|
|
|
|
IBM "Summit" series chipsets (ex: x440). This is available in IA32
|
|
|
|
|
and IA64 architectures.
|
|
|
|
|
* PIT (programmable interrupt timer): Intel 8253/8254 chipsets with a
|
2012-04-12 13:12:48 -04:00
|
|
|
|
configurable frequency in range 18.2 Hz - 1.2 MHz. It is a 16-bit
|
|
|
|
|
counter.
|
|
|
|
|
* RTC (Real-time clock). Most RTCs use a crystal oscillator with a
|
|
|
|
|
frequency of 32,768 Hz
|
2012-03-31 22:03:15 -04:00
|
|
|
|
|
2012-04-11 19:22:23 -04:00
|
|
|
|
|
|
|
|
|
Linux clocksource
|
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
|
|
There were 4 implementations of the time in the Linux kernel: UTIME
|
|
|
|
|
(1996), timer wheel (1997), HRT (2001) and hrtimers (2007). The
|
|
|
|
|
latter is the result of the "high-res-timers" project started by
|
|
|
|
|
George Anzinger in 2001, with contributions by Thomas Gleixner and
|
|
|
|
|
Douglas Niehaus. hrtimers implementation was merged into Linux
|
|
|
|
|
2.6.21, released in 2007.
|
|
|
|
|
|
|
|
|
|
hrtimers supports various clock sources. It sets a priority to each
|
|
|
|
|
source to decide which one will be used. Linux supports the following
|
|
|
|
|
clock sources:
|
|
|
|
|
|
|
|
|
|
* tsc
|
|
|
|
|
* hpet
|
|
|
|
|
* pit
|
|
|
|
|
* pmtmr: ACPI Power Management Timer
|
|
|
|
|
* cyclone
|
|
|
|
|
|
|
|
|
|
High-resolution timers are not supported on all hardware
|
|
|
|
|
architectures. They are at least provided on x86/x86_64, ARM and
|
|
|
|
|
PowerPC.
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
The ``/sys/devices/system/clocksource/clocksource0`` directory
|
|
|
|
|
contains two useful files:
|
2012-04-11 19:22:23 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* ``available_clocksource``: list of available clock sources
|
|
|
|
|
* ``current_clocksource``: clock source currently used. It is
|
|
|
|
|
possible to change the current clocksource by writing the name of a
|
|
|
|
|
clocksource into this file.
|
2012-04-11 19:22:23 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
``/proc/timer_list`` contains the list of all hardware timers.
|
2012-04-11 19:22:23 -04:00
|
|
|
|
|
|
|
|
|
Read also the `time(7) manual page
|
|
|
|
|
<http://www.kernel.org/doc/man-pages/online/pages/man7/time.7.html>`_:
|
|
|
|
|
"overview of time and timers".
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FreeBSD timecounter
|
|
|
|
|
-------------------
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
kern.timecounter.choice list available hardware clocks with their
|
|
|
|
|
priority. The sysctl program can be used to change the timecounter.
|
|
|
|
|
Example::
|
2012-04-11 19:22:23 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
# dmesg | grep Timecounter
|
2012-04-11 19:22:23 -04:00
|
|
|
|
Timecounter "i8254" frequency 1193182 Hz quality 0
|
|
|
|
|
Timecounter "ACPI-safe" frequency 3579545 Hz quality 850
|
|
|
|
|
Timecounter "HPET" frequency 100000000 Hz quality 900
|
|
|
|
|
Timecounter "TSC" frequency 3411154800 Hz quality 800
|
|
|
|
|
Timecounters tick every 10.000 msec
|
|
|
|
|
# sysctl kern.timecounter.choice
|
|
|
|
|
kern.timecounter.choice: TSC(800) HPET(900) ACPI-safe(850) i8254(0) dummy(-1000000)
|
|
|
|
|
# sysctl kern.timecounter.hardware="ACPI-fast"
|
|
|
|
|
kern.timecounter.hardware: HPET -> ACPI-fast
|
|
|
|
|
|
|
|
|
|
Available clocks:
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* "TSC": Time Stamp Counter of the processor
|
|
|
|
|
* "HPET": High Precision Event Timer
|
|
|
|
|
* "ACPI-fast": ACPI Power Management timer (fast mode)
|
|
|
|
|
* "ACPI-safe": ACPI Power Management timer (safe mode)
|
|
|
|
|
* "i8254": PIT with Intel 8254 chipset
|
2012-04-11 19:22:23 -04:00
|
|
|
|
|
|
|
|
|
The `commit 222222
|
2012-04-12 13:12:48 -04:00
|
|
|
|
<http://svnweb.freebsd.org/base?view=revision&revision=222222>`_ (May
|
|
|
|
|
2011) decreased ACPI-fast timecounter quality to 900 and increased
|
|
|
|
|
HPET timecounter quality to 950: "HPET on modern platforms usually
|
|
|
|
|
have better resolution and lower latency than ACPI timer".
|
2012-04-11 19:22:23 -04:00
|
|
|
|
|
|
|
|
|
Read `Timecounters: Efficient and precise timekeeping in SMP kernels
|
2012-04-12 13:12:48 -04:00
|
|
|
|
<http://phk.freebsd.dk/pubs/timecounter.pdf>`_ by Poul-Henning Kamp
|
|
|
|
|
(2002) for the FreeBSD Project.
|
2012-04-11 19:22:23 -04:00
|
|
|
|
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Performance
|
|
|
|
|
-----------
|
2012-04-11 19:22:23 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Reading an hardware clock has a cost. The following table compares
|
|
|
|
|
the performance of different hardware clocks on Linux 3.3 with Intel
|
|
|
|
|
Core i7-2600 at 3.40GHz (8 cores).
|
2012-04-11 16:48:14 -04:00
|
|
|
|
|
|
|
|
|
======================== ====== ======= ======
|
|
|
|
|
Function TSC ACPI PM HPET
|
|
|
|
|
======================== ====== ======= ======
|
|
|
|
|
time() 2 ns 2 ns 2 ns
|
|
|
|
|
CLOCK_REALTIME_COARSE 10 ns 10 ns 10 ns
|
|
|
|
|
CLOCK_MONOTONIC_COARSE 12 ns 13 ns 12 ns
|
|
|
|
|
CLOCK_THREAD_CPUTIME_ID 134 ns 135 ns 135 ns
|
|
|
|
|
CLOCK_PROCESS_CPUTIME_ID 127 ns 129 ns 129 ns
|
|
|
|
|
clock() 146 ns 146 ns 143 ns
|
|
|
|
|
gettimeofday() 23 ns 726 ns 637 ns
|
|
|
|
|
CLOCK_MONOTONIC_RAW 31 ns 716 ns 607 ns
|
|
|
|
|
CLOCK_REALTIME 27 ns 707 ns 629 ns
|
|
|
|
|
CLOCK_MONOTONIC 27 ns 723 ns 635 ns
|
|
|
|
|
======================== ====== ======= ======
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Each function was called 10,000,000 times and CLOCK_MONOTONIC was used
|
|
|
|
|
to get the time before and after. The benchmark was run 5 times to
|
|
|
|
|
keep the minimum time.
|
2012-04-11 16:48:14 -04:00
|
|
|
|
|
2012-04-11 18:19:16 -04:00
|
|
|
|
FreeBSD 8.0 in kvm with hardware virtualization:
|
|
|
|
|
|
|
|
|
|
======================== ====== ========= ======= =======
|
|
|
|
|
Function TSC ACPI-Safe HPET i8254
|
|
|
|
|
======================== ====== ========= ======= =======
|
|
|
|
|
time() 191 ns 188 ns 189 ns 188 ns
|
|
|
|
|
CLOCK_SECOND 187 ns 184 ns 187 ns 183 ns
|
|
|
|
|
CLOCK_REALTIME_FAST 189 ns 180 ns 187 ns 190 ns
|
|
|
|
|
CLOCK_UPTIME_FAST 191 ns 185 ns 186 ns 196 ns
|
|
|
|
|
CLOCK_MONOTONIC_FAST 188 ns 187 ns 188 ns 189 ns
|
|
|
|
|
CLOCK_THREAD_CPUTIME_ID 208 ns 206 ns 207 ns 220 ns
|
|
|
|
|
CLOCK_VIRTUAL 280 ns 279 ns 283 ns 296 ns
|
|
|
|
|
CLOCK_PROF 289 ns 280 ns 282 ns 286 ns
|
|
|
|
|
clock() 342 ns 340 ns 337 ns 344 ns
|
|
|
|
|
CLOCK_UPTIME_PRECISE 197 ns 10380 ns 4402 ns 4097 ns
|
|
|
|
|
CLOCK_REALTIME 196 ns 10376 ns 4337 ns 4054 ns
|
|
|
|
|
CLOCK_MONOTONIC_PRECISE 198 ns 10493 ns 4413 ns 3958 ns
|
|
|
|
|
CLOCK_UPTIME 197 ns 10523 ns 4458 ns 4058 ns
|
|
|
|
|
gettimeofday() 202 ns 10524 ns 4186 ns 3962 ns
|
|
|
|
|
CLOCK_REALTIME_PRECISE 197 ns 10599 ns 4394 ns 4060 ns
|
|
|
|
|
CLOCK_MONOTONIC 201 ns 10766 ns 4498 ns 3943 ns
|
|
|
|
|
======================== ====== ========= ======= =======
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Each function was called 100,000 times and CLOCK_MONOTONIC was used to
|
|
|
|
|
get the time before and after. The benchmark was run 5 times to keep
|
|
|
|
|
the minimum time.
|
2012-04-11 16:48:14 -04:00
|
|
|
|
|
2012-03-31 22:03:15 -04:00
|
|
|
|
|
2012-04-03 20:57:55 -04:00
|
|
|
|
NTP adjustment
|
|
|
|
|
==============
|
2012-04-02 18:18:51 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
NTP has different methods to adjust a clock:
|
2012-04-02 18:18:51 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* "slewing": change the clock frequency to be slightly faster or
|
|
|
|
|
slower (which is done with ``adjtime()``). Since the slew rate is
|
2012-04-13 17:24:44 -04:00
|
|
|
|
limited to 0.5 millisecond per second, each second of adjustment requires an
|
|
|
|
|
amortization interval of 2000 seconds. Thus, an adjustment of many
|
2012-04-12 13:12:48 -04:00
|
|
|
|
seconds can take hours or days to amortize.
|
|
|
|
|
* "stepping": jump by a large amount in a single discrete step (which
|
|
|
|
|
is done with ``settimeofday()``)
|
2012-04-02 18:18:51 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
By default, the time is slewed if the offset is less than 128 ms, or
|
|
|
|
|
stepped otherwise.
|
2012-04-02 18:18:51 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Slewing is generally desirable (i.e. we should use CLOCK_MONOTONIC,
|
|
|
|
|
not CLOCK_MONOTONIC_RAW) if one wishes to measure "real" time (and not
|
|
|
|
|
a time-like object like CPU cycles). This is because the clock on the
|
|
|
|
|
other end of the NTP connection from you is probably better at keeping
|
|
|
|
|
time: hopefully that thirty five thousand dollars of Cesium
|
|
|
|
|
timekeeping goodness is doing something better than your PC's $3
|
|
|
|
|
quartz crystal, after all.
|
2012-04-02 18:18:51 -04:00
|
|
|
|
|
|
|
|
|
Get more detail in the `documentation of the NTP daemon
|
|
|
|
|
<http://doc.ntp.org/4.1.2/ntpd.htm>`_.
|
|
|
|
|
|
|
|
|
|
|
2012-04-13 20:22:50 -04:00
|
|
|
|
Operating system time functions
|
|
|
|
|
===============================
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-03-30 19:39:46 -04:00
|
|
|
|
Monotonic clocks
|
|
|
|
|
----------------
|
2012-03-29 21:41:03 -04:00
|
|
|
|
|
2012-04-10 18:42:54 -04:00
|
|
|
|
========================= ========== =============== ============= ===============
|
|
|
|
|
Name Resolution Adjusted Include sleep Include suspend
|
|
|
|
|
========================= ========== =============== ============= ===============
|
2012-04-13 18:47:00 -04:00
|
|
|
|
gethrtime() 1 ns No Yes Yes
|
2012-04-13 20:08:16 -04:00
|
|
|
|
CLOCK_HIGHRES 1 ns No Yes Yes
|
2012-04-10 18:42:54 -04:00
|
|
|
|
CLOCK_MONOTONIC 1 ns Slewed on Linux Yes No
|
2012-04-13 18:47:00 -04:00
|
|
|
|
CLOCK_MONOTONIC_COARSE 1 ns Slewed on Linux Yes No
|
2012-04-10 18:42:54 -04:00
|
|
|
|
CLOCK_MONOTONIC_RAW 1 ns No Yes No
|
2012-04-12 08:01:02 -04:00
|
|
|
|
CLOCK_BOOTTIME 1 ns ? Yes Yes
|
2012-04-13 17:24:44 -04:00
|
|
|
|
CLOCK_UPTIME 1 ns No Yes ?
|
2012-04-10 18:58:33 -04:00
|
|
|
|
mach_absolute_time() 1 ns No Yes No
|
2012-04-10 18:42:54 -04:00
|
|
|
|
QueryPerformanceCounter() \- No Yes ?
|
|
|
|
|
GetTickCount[64]() 1 ms No Yes Yes
|
|
|
|
|
timeGetTime() 1 ms No Yes ?
|
|
|
|
|
========================= ========== =============== ============= ===============
|
2012-03-30 17:16:06 -04:00
|
|
|
|
|
2012-04-11 18:39:22 -04:00
|
|
|
|
Examples of clock precision on x86_64:
|
2012-04-02 18:18:51 -04:00
|
|
|
|
|
2012-04-13 16:07:36 -04:00
|
|
|
|
========================= ================ ========= ===================
|
|
|
|
|
Name Operating system Precision Precision in Python
|
|
|
|
|
========================= ================ ========= ===================
|
2012-04-13 18:17:54 -04:00
|
|
|
|
CLOCK_HIGHRES SunOS 5.11 2 ns 2 µs
|
2012-04-13 17:24:44 -04:00
|
|
|
|
CLOCK_MONOTONIC Linux 3.2 1 ns 2 µs
|
2012-04-13 18:17:54 -04:00
|
|
|
|
CLOCK_MONOTONIC SunOS 5.11 2 ns 3 µs
|
|
|
|
|
CLOCK_MONOTONIC_RAW Linux 3.2 1 ns 3 µs
|
2012-04-13 19:14:34 -04:00
|
|
|
|
CLOCK_BOOTTIME Linux 3.3 1 ns 3 µs
|
2012-04-13 17:24:44 -04:00
|
|
|
|
CLOCK_MONOTONIC FreeBSD 8.2 11 ns 7 µs
|
2012-04-13 18:17:54 -04:00
|
|
|
|
CLOCK_MONOTONIC OpenBSD 5.0 10 ms 7 µs
|
|
|
|
|
QueryPerformanceCounter Windows Seven 10 ns 9 µs
|
|
|
|
|
CLOCK_UPTIME FreeBSD 8.2 11 ns 9 µs
|
2012-04-13 18:47:00 -04:00
|
|
|
|
CLOCK_MONOTONIC_COARSE Linux 3.3 1 ms 1 ms
|
2012-04-13 18:17:54 -04:00
|
|
|
|
GetTickCount Windows Seven 16 ms 15 ms
|
2012-04-13 16:07:36 -04:00
|
|
|
|
========================= ================ ========= ===================
|
2012-04-02 18:18:51 -04:00
|
|
|
|
|
2012-03-27 20:18:11 -04:00
|
|
|
|
mach_absolute_time
|
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
Mac OS X provides a monotonic clock: mach_absolute_time(). It is
|
|
|
|
|
based on absolute elapsed time delta since system boot. It is not
|
|
|
|
|
adjusted and cannot be set.
|
2012-03-27 20:18:11 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
mach_timebase_info() gives a fraction to convert the clock value to a
|
|
|
|
|
number of nanoseconds. According to the documentation (`Technical Q&A
|
|
|
|
|
QA1398 <https://developer.apple.com/library/mac/#qa/qa1398/>`_),
|
2012-04-12 13:12:48 -04:00
|
|
|
|
mach_timebase_info() is always equal to one and never fails, even if
|
|
|
|
|
the function may fail according to its prototype.
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-03-31 02:53:07 -04:00
|
|
|
|
mach_absolute_time() stops during a sleep on a PowerPC CPU, but not on
|
|
|
|
|
an Intel CPU: `Different behaviour of mach_absolute_time() on i386/ppc
|
2012-03-29 22:21:11 -04:00
|
|
|
|
<http://lists.apple.com/archives/PerfOptimization-dev/2006/Jul/msg00024.html>`_.
|
|
|
|
|
|
2012-04-12 16:26:43 -04:00
|
|
|
|
CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
2012-03-27 20:18:11 -04:00
|
|
|
|
|
2012-03-31 02:53:07 -04:00
|
|
|
|
CLOCK_MONOTONIC and CLOCK_MONOTONIC_RAW represent monotonic time since
|
2012-04-13 18:47:00 -04:00
|
|
|
|
some unspecified starting point. They cannot be set. The precision
|
|
|
|
|
can be read using ``clock_getres()``.
|
2012-03-27 20:18:11 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
Documentation: refer to the manual page of your operating system.
|
|
|
|
|
Examples:
|
2012-03-28 20:10:32 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* `FreeBSD clock_gettime() manual page
|
|
|
|
|
<http://www.freebsd.org/cgi/man.cgi?query=clock_gettime>`_
|
|
|
|
|
* `Linux clock_gettime() manual page
|
|
|
|
|
<http://linux.die.net/man/3/clock_gettime>`_
|
2012-03-28 20:10:32 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
CLOCK_MONOTONIC is available at least on the following operating
|
|
|
|
|
systems:
|
2012-03-28 18:57:15 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* DragonFly BSD, FreeBSD >= 5.0, OpenBSD, NetBSD
|
|
|
|
|
* Linux
|
|
|
|
|
* Solaris
|
2012-03-28 18:57:15 -04:00
|
|
|
|
|
|
|
|
|
The following operating systems don't support CLOCK_MONOTONIC:
|
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* GNU/Hurd (see `open issues/ clock_gettime
|
|
|
|
|
<http://www.gnu.org/software/hurd/open_issues/clock_gettime.html>`_)
|
|
|
|
|
* Mac OS X
|
|
|
|
|
* Windows
|
2012-03-28 18:57:15 -04:00
|
|
|
|
|
2012-04-02 18:18:51 -04:00
|
|
|
|
On Linux, NTP may adjust the CLOCK_MONOTONIC rate (slewed), but it cannot
|
|
|
|
|
jump backward.
|
2012-03-28 18:57:15 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
CLOCK_MONOTONIC_RAW is specific to Linux. It is similar to
|
|
|
|
|
CLOCK_MONOTONIC, but provides access to a raw hardware-based time that
|
|
|
|
|
is not subject to NTP adjustments. CLOCK_MONOTONIC_RAW requires Linux
|
|
|
|
|
2.6.28 or later.
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-12 16:26:43 -04:00
|
|
|
|
Linux 2.6.39 and glibc 2.14 introduces a new clock: CLOCK_BOOTTIME.
|
|
|
|
|
CLOCK_BOOTTIME is idential to CLOCK_MONOTONIC, except that it also
|
|
|
|
|
includes any time spent in suspend. Read also `Waking systems from
|
|
|
|
|
suspend <http://lwn.net/Articles/429925/>`_ (March, 2011).
|
|
|
|
|
|
2012-03-27 20:18:11 -04:00
|
|
|
|
CLOCK_MONOTONIC stops while the machine is suspended.
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-13 18:47:00 -04:00
|
|
|
|
Linux provides also CLOCK_MONOTONIC_COARSE since Linux 2.6.32. It is
|
|
|
|
|
similar to CLOCK_MONOTONIC, less precise but faster.
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
``clock_gettime()`` fails if the system does not support the specified
|
2012-03-31 02:53:07 -04:00
|
|
|
|
clock, even if the standard C library supports it. For example,
|
2012-03-31 02:38:41 -04:00
|
|
|
|
CLOCK_MONOTONIC_RAW requires a kernel version 2.6.28 or later.
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
|
2012-03-28 09:02:58 -04:00
|
|
|
|
Windows: QueryPerformanceCounter
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
2012-03-27 20:18:11 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
High-resolution performance counter. It is monotonic.
|
2012-04-13 18:47:00 -04:00
|
|
|
|
The frequency of the counter can be read using QueryPerformanceFrequency().
|
|
|
|
|
The precision is 1 / QueryPerformanceFrequency().
|
2012-03-28 20:10:32 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
It has a much higher resolution, but has lower long term precision
|
|
|
|
|
than GetTickCount() and timeGetTime() clocks. For example, it will
|
|
|
|
|
drift compared to the low precision clocks.
|
2012-03-29 21:41:03 -04:00
|
|
|
|
|
2012-03-28 20:10:32 -04:00
|
|
|
|
Documentation:
|
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* `MSDN: QueryPerformanceCounter() documentation
|
|
|
|
|
<http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904%28v=vs.85%29.aspx>`_
|
|
|
|
|
* `MSDN: QueryPerformanceFrequency() documentation
|
|
|
|
|
<http://msdn.microsoft.com/en-us/library/windows/desktop/ms644905%28v=vs.85%29.aspx>`_
|
2012-03-28 20:10:32 -04:00
|
|
|
|
|
|
|
|
|
Hardware clocks used by QueryPerformanceCounter:
|
2012-03-27 20:18:11 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* Windows XP: RDTSC instruction of Intel processors, the clock
|
|
|
|
|
frequency is the frequency of the processor (between 200 MHz and 3
|
2012-03-31 02:53:07 -04:00
|
|
|
|
GHz, usually greater than 1 GHz nowadays).
|
|
|
|
|
* Windows 2000: ACPI power management timer, frequency = 3,549,545 Hz.
|
|
|
|
|
It can be forced through the "/usepmtimer" flag in boot.ini.
|
2012-03-31 02:38:41 -04:00
|
|
|
|
|
|
|
|
|
.. * Windows 95/98: 8245 PIT chipset, frequency = 1,193,181 Hz
|
2012-03-27 20:18:11 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
QueryPerformanceFrequency() should only be called once: the frequency
|
|
|
|
|
will not change while the system is running. It fails if the
|
|
|
|
|
installed hardware does not support a high-resolution performance
|
|
|
|
|
counter.
|
2012-03-27 20:18:11 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
QueryPerformanceCounter() cannot be adjusted:
|
|
|
|
|
`SetSystemTimeAdjustment()
|
2012-03-29 21:41:03 -04:00
|
|
|
|
<http://msdn.microsoft.com/en-us/library/windows/desktop/ms724943(v=vs.85).aspx>`_
|
2012-03-31 02:53:07 -04:00
|
|
|
|
only adjusts the system time.
|
2012-03-29 21:41:03 -04:00
|
|
|
|
|
2012-03-28 19:57:15 -04:00
|
|
|
|
Bugs:
|
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* The performance counter value may unexpectedly leap forward because
|
2012-03-31 02:53:07 -04:00
|
|
|
|
of a hardware bug, see `KB274323`_.
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* On VirtualBox, QueryPerformanceCounter() does not increment the high
|
|
|
|
|
part every time the low part overflows, see `Monotonic timers
|
|
|
|
|
<http://code-factor.blogspot.fr/2009/11/monotonic-timers.html>`_
|
|
|
|
|
(2009).
|
|
|
|
|
* VirtualBox had a bug in its HPET virtualized device:
|
|
|
|
|
QueryPerformanceCounter() did jump forward by approx. 42 seconds (`issue
|
|
|
|
|
#8707 <https://www.virtualbox.org/ticket/8707>`_).
|
|
|
|
|
* Windows XP had a bug (see `KB896256`_): on a multiprocessor
|
|
|
|
|
computer, QueryPerformanceCounter() returned a different value for
|
|
|
|
|
each processor. The bug was fixed in Windows XP SP2.
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* Issues with processor with variable frequency: the frequency is
|
|
|
|
|
changed depending on the workload to reduce memory consumption.
|
|
|
|
|
* Chromium don't use QueryPerformanceCounter() on Athlon X2 CPUs
|
|
|
|
|
(model 15) because "QueryPerformanceCounter is unreliable" (see
|
|
|
|
|
base/time_win.cc in Chromium source code)
|
2012-03-28 19:57:15 -04:00
|
|
|
|
|
2012-03-28 19:11:16 -04:00
|
|
|
|
.. _KB896256: http://support.microsoft.com/?id=896256
|
|
|
|
|
.. _KB274323: http://support.microsoft.com/?id=274323
|
|
|
|
|
|
2012-03-27 20:18:11 -04:00
|
|
|
|
|
2012-03-28 09:02:58 -04:00
|
|
|
|
Windows: GetTickCount(), GetTickCount64()
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
2012-03-27 20:18:11 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
GetTickCount() and GetTickCount64() are monotonic, cannot fail and are
|
|
|
|
|
not adjusted by SetSystemTimeAdjustment(). MSDN documentation:
|
|
|
|
|
`GetTickCount()
|
|
|
|
|
<http://msdn.microsoft.com/en-us/library/windows/desktop/ms724408(v=vs.85).aspx>`_,
|
|
|
|
|
`GetTickCount64()
|
|
|
|
|
<http://msdn.microsoft.com/en-us/library/windows/desktop/ms724411(v=vs.85).aspx>`_.
|
2012-04-13 18:47:00 -04:00
|
|
|
|
The precision can be read using GetSystemTimeAdjustment().
|
2012-03-27 20:18:11 -04:00
|
|
|
|
|
2012-03-31 02:53:07 -04:00
|
|
|
|
The elapsed time retrieved by GetTickCount() or GetTickCount64()
|
|
|
|
|
includes time the system spends in sleep or hibernation.
|
2012-03-29 22:21:11 -04:00
|
|
|
|
|
2012-03-27 20:18:11 -04:00
|
|
|
|
GetTickCount64() was added to Windows Vista and Windows Server 2008.
|
|
|
|
|
|
2012-04-12 20:16:55 -04:00
|
|
|
|
It is possible to improve the precision using the `undocumented
|
|
|
|
|
NtSetTimerResolution() function
|
2012-03-28 18:57:15 -04:00
|
|
|
|
<http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Time/NtSetTimerResolution.html>`_.
|
2012-04-12 20:16:55 -04:00
|
|
|
|
There are applications using this undocumented function, example: `Timer
|
|
|
|
|
Resolution <http://www.lucashale.com/timer-resolution/>`_.
|
2012-03-28 18:57:15 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
WaitForSingleObject() uses the same timer as GetTickCount() with the
|
2012-04-12 20:16:55 -04:00
|
|
|
|
same precision.
|
2012-03-31 22:03:15 -04:00
|
|
|
|
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-03-29 21:41:03 -04:00
|
|
|
|
Windows: timeGetTime
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
The timeGetTime function retrieves the system time, in milliseconds.
|
2012-03-31 02:53:07 -04:00
|
|
|
|
The system time is the time elapsed since Windows was started. Read
|
2012-03-31 02:38:41 -04:00
|
|
|
|
the `timeGetTime() documentation
|
2012-03-29 21:41:03 -04:00
|
|
|
|
<http://msdn.microsoft.com/en-us/library/windows/desktop/dd757629(v=vs.85).aspx>`_.
|
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
The return type of timeGetTime() is a 32-bit unsigned integer. As
|
|
|
|
|
GetTickCount(), timeGetTime() rolls over after 2^32 milliseconds (49.7
|
|
|
|
|
days).
|
2012-03-29 21:41:03 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
The elapsed time retrieved by timeGetTime() includes time the system
|
|
|
|
|
spends in sleep.
|
2012-04-10 18:42:54 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
The default precision of the timeGetTime function can be five
|
|
|
|
|
milliseconds or more, depending on the machine.
|
2012-03-29 21:41:03 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
timeBeginPeriod() can be used to increase the precision of
|
|
|
|
|
timeGetTime() up to 1 millisecond, but it negatively affects power
|
|
|
|
|
consumption. Calling timeBeginPeriod() also affects the granularity
|
|
|
|
|
of some other timing calls, such as CreateWaitableTimer(),
|
|
|
|
|
WaitForSingleObject() and Sleep().
|
2012-03-29 21:41:03 -04:00
|
|
|
|
|
|
|
|
|
.. note::
|
2012-03-31 02:53:07 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
timeGetTime() and timeBeginPeriod() are part the Windows multimedia
|
2012-03-31 02:53:07 -04:00
|
|
|
|
library and so require to link the program against winmm or to
|
|
|
|
|
dynamically load the library.
|
2012-03-29 21:41:03 -04:00
|
|
|
|
|
2012-03-28 09:02:58 -04:00
|
|
|
|
Solaris: CLOCK_HIGHRES
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
2012-03-31 02:53:07 -04:00
|
|
|
|
The Solaris OS has a CLOCK_HIGHRES timer that attempts to use an
|
2012-03-31 02:38:41 -04:00
|
|
|
|
optimal hardware source, and may give close to nanosecond resolution.
|
|
|
|
|
CLOCK_HIGHRES is the nonadjustable, high-resolution clock. For timers
|
|
|
|
|
created with a clockid_t value of CLOCK_HIGHRES, the system will
|
|
|
|
|
attempt to use an optimal hardware source.
|
2012-03-28 09:02:58 -04:00
|
|
|
|
|
2012-04-13 18:47:00 -04:00
|
|
|
|
The precision of CLOCK_HIGHRES can be read using ``clock_getres()``.
|
|
|
|
|
|
2012-03-28 09:02:58 -04:00
|
|
|
|
Solaris: gethrtime
|
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
The gethrtime() function returns the current high-resolution real
|
|
|
|
|
time. Time is expressed as nanoseconds since some arbitrary time in
|
|
|
|
|
the past; it is not correlated in any way to the time of day, and thus
|
|
|
|
|
is not subject to resetting or drifting by way of adjtime() or
|
|
|
|
|
settimeofday(). The hires timer is ideally suited to performance
|
|
|
|
|
measurement tasks, where cheap, accurate interval timing is required.
|
2012-03-28 09:02:58 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
The linearity of gethrtime() is not preserved across a suspend-resume
|
|
|
|
|
cycle (`Bug 4272663 <http://wesunsolve.net/bugid/id/4272663>`_).
|
2012-03-29 22:21:11 -04:00
|
|
|
|
|
2012-03-29 21:55:35 -04:00
|
|
|
|
Read the `gethrtime() manual page of Solaris 11
|
|
|
|
|
<http://docs.oracle.com/cd/E23824_01/html/821-1465/gethrtime-3c.html#scrolltoc>`_.
|
|
|
|
|
|
2012-03-28 09:02:58 -04:00
|
|
|
|
On Solaris, gethrtime() is the same as clock_gettime(CLOCK_MONOTONIC).
|
|
|
|
|
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-03-30 19:39:46 -04:00
|
|
|
|
System time clocks
|
|
|
|
|
------------------
|
2012-03-30 17:16:06 -04:00
|
|
|
|
|
2012-04-13 20:08:16 -04:00
|
|
|
|
========================= =============== ============= ===============
|
|
|
|
|
Name Resolution Include sleep Include suspend
|
|
|
|
|
========================= =============== ============= ===============
|
|
|
|
|
CLOCK_REALTIME 1 ns Yes Yes
|
|
|
|
|
CLOCK_REALTIME_COARSE 1 ns Yes Yes
|
|
|
|
|
GetSystemTimeAsFileTime 100 ns Yes Yes
|
|
|
|
|
gettimeofday() 1 µs Yes Yes
|
|
|
|
|
ftime() 1 ms Yes Yes
|
|
|
|
|
time() 1 sec Yes Yes
|
|
|
|
|
========================= =============== ============= ===============
|
2012-04-02 18:18:51 -04:00
|
|
|
|
|
2012-04-11 18:39:22 -04:00
|
|
|
|
Examples of clock precision on x86_64:
|
2012-04-02 18:18:51 -04:00
|
|
|
|
|
2012-04-13 16:07:36 -04:00
|
|
|
|
========================= ================ ========= ===================
|
|
|
|
|
Name Operating system Precision Precision in Python
|
|
|
|
|
========================= ================ ========= ===================
|
2012-04-13 18:17:54 -04:00
|
|
|
|
CLOCK_REALTIME SunOS 5.11 10 ms 2 µs
|
2012-04-13 17:24:44 -04:00
|
|
|
|
CLOCK_REALTIME Linux 3.2 1 ns 2 µs
|
|
|
|
|
CLOCK_REALTIME FreeBSD 8.2 11 ns 7 µs
|
2012-04-13 18:17:54 -04:00
|
|
|
|
CLOCK_REALTIME OpenBSD 5.0 10 ms 10 µs
|
2012-04-13 18:47:00 -04:00
|
|
|
|
CLOCK_REALTIME_COARSE Linux 3.3 1 ms 1 ms
|
2012-04-13 18:17:54 -04:00
|
|
|
|
GetSystemTimeAsFileTime Windows Seven 16 ms 1 ms
|
2012-04-13 16:07:36 -04:00
|
|
|
|
========================= ================ ========= ===================
|
2012-04-02 18:18:51 -04:00
|
|
|
|
|
2012-03-30 17:16:06 -04:00
|
|
|
|
|
2012-03-27 20:18:11 -04:00
|
|
|
|
Windows: GetSystemTimeAsFileTime
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-12 20:16:55 -04:00
|
|
|
|
The system time can be read using GetSystemTimeAsFileTime(), ftime() and
|
|
|
|
|
time(). The precision of the system clock can be read using
|
|
|
|
|
GetSystemTimeAdjustment().
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-10 19:23:28 -04:00
|
|
|
|
Read the `GetSystemTimeAsFileTime() documentation
|
|
|
|
|
<http://msdn.microsoft.com/en-us/library/windows/desktop/ms724397(v=vs.85).aspx>`_.
|
|
|
|
|
|
2012-03-26 19:12:03 -04:00
|
|
|
|
The system time can be set using SetSystemTime().
|
|
|
|
|
|
|
|
|
|
System time on UNIX
|
|
|
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
2012-04-13 18:47:00 -04:00
|
|
|
|
gettimeofday(), ftime(), time() and clock_gettime(CLOCK_REALTIME) return
|
|
|
|
|
the system clock. The precision of CLOCK_REALTIME can be read using
|
|
|
|
|
clock_getres().
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
The system time can be set using settimeofday() or
|
|
|
|
|
clock_settime(CLOCK_REALTIME).
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-13 18:47:00 -04:00
|
|
|
|
Linux provides also CLOCK_REALTIME_COARSE since Linux 2.6.32. It is similar
|
|
|
|
|
to CLOCK_REALTIME, less precise but faster.
|
|
|
|
|
|
2012-04-12 17:56:58 -04:00
|
|
|
|
Alexander Shishkin proposed an API for Linux to be notified when the system
|
|
|
|
|
clock is changed: `timerfd: add TFD_NOTIFY_CLOCK_SET to watch for clock changes
|
|
|
|
|
<http://lwn.net/Articles/432395/>`_ (4th version of the API, March 2011). The
|
|
|
|
|
API is not accepted yet, CLOCK_BOOTTIME provides a similar feature.
|
|
|
|
|
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-02 19:14:28 -04:00
|
|
|
|
Process time
|
|
|
|
|
------------
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
The process time cannot be set. It is not monotonic: the clocks stop
|
|
|
|
|
while the process is idle.
|
2012-04-02 19:14:28 -04:00
|
|
|
|
|
2012-04-13 20:08:16 -04:00
|
|
|
|
========================= ========== ============= ===============
|
|
|
|
|
Name Resolution Include sleep Include suspend
|
|
|
|
|
========================= ========== ============= ===============
|
|
|
|
|
GetProcessTimes() 100 ns No No
|
|
|
|
|
CLOCK_PROCESS_CPUTIME_ID 1 ns No No
|
|
|
|
|
getrusage(RUSAGE_SELF) 1 µs No No
|
|
|
|
|
times() \- No No
|
|
|
|
|
clock() \- No (*) No
|
|
|
|
|
========================= ========== ============= ===============
|
2012-04-02 19:14:28 -04:00
|
|
|
|
|
2012-04-12 16:42:11 -04:00
|
|
|
|
(*) On Windows, clock() does include time elapsed during a sleep. It does not
|
|
|
|
|
on other operating systems.
|
|
|
|
|
|
2012-04-11 18:39:22 -04:00
|
|
|
|
Examples of clock precision on x86_64:
|
2012-04-02 19:14:28 -04:00
|
|
|
|
|
2012-04-13 16:07:36 -04:00
|
|
|
|
========================= ================ ========= ===================
|
|
|
|
|
Name Operating system Precision Precision in Python
|
|
|
|
|
========================= ================ ========= ===================
|
2012-04-13 18:17:54 -04:00
|
|
|
|
getrusage(RUSAGE_SELF) FreeBSD 8.2 \- 1 µs
|
2012-04-13 17:24:44 -04:00
|
|
|
|
CLOCK_PROCESS_CPUTIME_ID Linux 3.2 1 ns 3 µs
|
2012-04-13 18:17:54 -04:00
|
|
|
|
getrusage(RUSAGE_SELF) SunOS 5.11 \- 3 µs
|
2012-04-13 19:14:34 -04:00
|
|
|
|
getrusage(RUSAGE_SELF) Linux 3.3 \- 1 ms
|
2012-04-13 18:17:54 -04:00
|
|
|
|
getrusage(RUSAGE_SELF) OpenBSD 5.0 \- 8 ms
|
2012-04-13 17:24:44 -04:00
|
|
|
|
clock() FreeBSD 8.2 8 ms 8 ms
|
2012-04-13 16:07:36 -04:00
|
|
|
|
clock() Linux 3.2 1 µs 10 ms
|
|
|
|
|
times() Linux 3.0 10 ms 10 ms
|
2012-04-13 18:17:54 -04:00
|
|
|
|
clock() OpenBSD 5.0 10 ms 10 ms
|
|
|
|
|
times() OpenBSD 5.0 10 ms 10 ms
|
|
|
|
|
GetProcessTimes() Windows Seven 16 ms 16 ms
|
|
|
|
|
clock() SunOS 5.11 1 µs 10 ms
|
2012-04-13 16:07:36 -04:00
|
|
|
|
========================= ================ ========= ===================
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-02 19:14:28 -04:00
|
|
|
|
Functions
|
|
|
|
|
^^^^^^^^^
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-12 20:16:55 -04:00
|
|
|
|
* Windows: GetProcessTimes(). The precision can be read using
|
|
|
|
|
GetSystemTimeAdjustment().
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* clock_gettime(CLOCK_PROCESS_CPUTIME_ID): High-resolution per-process
|
2012-04-13 18:47:00 -04:00
|
|
|
|
timer from the CPU. The precision can be read using clock_getres().
|
|
|
|
|
* clock(). The precision is 1 / CLOCKS_PER_SEC.
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* Windows: The elapsed wall-clock time since the start of the
|
2012-03-31 02:53:07 -04:00
|
|
|
|
process (elapsed time in seconds times CLOCKS_PER_SEC). It can
|
2012-03-31 02:38:41 -04:00
|
|
|
|
fail.
|
|
|
|
|
* UNIX: returns an approximation of processor time used by the
|
|
|
|
|
program.
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-13 18:47:00 -04:00
|
|
|
|
* getrusage(RUSAGE_SELF) returns a structure of resource usage of the currenet
|
|
|
|
|
process. ru_utime is use CPU time and ru_stime is the system CPU time.
|
|
|
|
|
* times(): structure of process times. The precision is 1 / ticks_per_seconds,
|
|
|
|
|
where ticks_per_seconds is sysconf(_SC_CLK_TCK) or the HZ constant.
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-12 07:38:06 -04:00
|
|
|
|
Python source code includes a portable library to get the process time (CPU
|
|
|
|
|
time): `Tools/pybench/systimes.py
|
|
|
|
|
<http://hg.python.org/cpython/file/tip/Tools/pybench/systimes.py>`_.
|
|
|
|
|
|
2012-04-13 20:08:16 -04:00
|
|
|
|
See also the `QueryProcessCycleTime() function
|
|
|
|
|
<http://msdn.microsoft.com/en-us/library/windows/desktop/ms684929(v=vs.85).aspx>`_
|
|
|
|
|
(sum of the cycle time of all threads).
|
|
|
|
|
|
2012-04-02 19:14:28 -04:00
|
|
|
|
|
|
|
|
|
Thread time
|
|
|
|
|
-----------
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
The thread time cannot be set. It is not monotonic: the clocks stop
|
|
|
|
|
while the thread is idle.
|
2012-04-02 19:14:28 -04:00
|
|
|
|
|
2012-04-13 20:08:16 -04:00
|
|
|
|
========================= ========== ============= ===============
|
|
|
|
|
Name Resolution Include sleep Include suspend
|
|
|
|
|
========================= ========== ============= ===============
|
|
|
|
|
CLOCK_THREAD_CPUTIME_ID 1 ns Yes Epoch changes
|
|
|
|
|
GetThreadTimes() 100 ns No ?
|
|
|
|
|
========================= ========== ============= ===============
|
2012-04-02 19:14:28 -04:00
|
|
|
|
|
2012-04-11 18:39:22 -04:00
|
|
|
|
Examples of clock precision on x86_64:
|
2012-04-02 18:18:51 -04:00
|
|
|
|
|
2012-04-13 16:07:36 -04:00
|
|
|
|
========================= ================ =============== ===================
|
|
|
|
|
Name Operating system Precision Precision in Python
|
|
|
|
|
========================= ================ =============== ===================
|
2012-04-13 17:24:44 -04:00
|
|
|
|
CLOCK_THREAD_CPUTIME_ID FreeBSD 8.2 1 µs 1 µs
|
2012-04-13 18:17:54 -04:00
|
|
|
|
CLOCK_THREAD_CPUTIME_ID Linux 3.2 1 ns 6 µs
|
|
|
|
|
GetThreadTimes() Windows Seven 16 ms 16 ms
|
2012-04-13 16:07:36 -04:00
|
|
|
|
========================= ================ =============== ===================
|
2012-04-02 18:18:51 -04:00
|
|
|
|
|
2012-04-13 20:08:16 -04:00
|
|
|
|
CLOCK_THREAD_CPUTIME_ID returns a number of CPU cycles, not a number of
|
|
|
|
|
seconds.
|
|
|
|
|
|
2012-04-02 18:18:51 -04:00
|
|
|
|
|
2012-04-02 19:14:28 -04:00
|
|
|
|
Functions
|
|
|
|
|
^^^^^^^^^
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-12 20:16:55 -04:00
|
|
|
|
* Windows: GetThreadTimes(). The precision can be read using
|
2012-04-13 20:08:16 -04:00
|
|
|
|
GetSystemTimeAdjustment(). `MSDN documentation of GetThreadTimes()
|
|
|
|
|
<http://msdn.microsoft.com/en-us/library/windows/desktop/ms683237(v=vs.85).aspx>`_.
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* clock_gettime(CLOCK_THREAD_CPUTIME_ID): Thread-specific CPU-time
|
2012-04-13 18:47:00 -04:00
|
|
|
|
clock. The precision can be read using of clock_getres().
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-13 20:08:16 -04:00
|
|
|
|
See also the `QueryThreadCycleTime() function
|
|
|
|
|
<http://msdn.microsoft.com/en-us/library/windows/desktop/ms684943(v=vs.85).aspx>`_
|
|
|
|
|
(cycle time for the specified thread) and pthread_getcpuclockid().
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
|
|
|
|
|
2012-03-28 09:02:58 -04:00
|
|
|
|
Windows: QueryUnbiasedInterruptTime
|
2012-04-02 19:14:28 -04:00
|
|
|
|
-----------------------------------
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
Gets the current unbiased interrupt time from the biased interrupt
|
|
|
|
|
time and the current sleep bias amount. This time is not affected by
|
|
|
|
|
power management sleep transitions.
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
The elapsed time retrieved by the QueryUnbiasedInterruptTime function
|
|
|
|
|
includes only time that the system spends in the working state.
|
2012-03-29 22:21:11 -04:00
|
|
|
|
QueryUnbiasedInterruptTime() is not monotonic.
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
|
|
|
|
QueryUnbiasedInterruptTime() was introduced in Windows 7.
|
|
|
|
|
|
2012-04-13 20:08:16 -04:00
|
|
|
|
See also `QueryIdleProcessorCycleTime() function
|
|
|
|
|
<http://msdn.microsoft.com/en-us/library/windows/desktop/ms684922(v=vs.85).aspx>`_
|
|
|
|
|
(cycle time for the idle thread of each processor)
|
|
|
|
|
|
2012-03-31 02:53:07 -04:00
|
|
|
|
|
2012-04-13 20:22:50 -04:00
|
|
|
|
Sleep
|
2012-04-10 07:58:42 -04:00
|
|
|
|
-----
|
|
|
|
|
|
2012-04-13 20:22:50 -04:00
|
|
|
|
Suspend execution of the process for the given number of seconds. Sleep is not
|
|
|
|
|
affected by system clock update. Sleep is paused during system suspend. For
|
|
|
|
|
example, if a process sleeps for 60 seconds and the system is suspended for 30
|
|
|
|
|
seconds in the middle of the sleep, the sleep duration is 90 seconds in the
|
|
|
|
|
real time.
|
2012-04-08 19:32:02 -04:00
|
|
|
|
|
|
|
|
|
Sleep can be interrupted by a signal: the function fails with EINTR.
|
|
|
|
|
|
|
|
|
|
======================== ==========
|
|
|
|
|
Name Resolution
|
|
|
|
|
======================== ==========
|
|
|
|
|
nanosleep() 1 ns
|
|
|
|
|
clock_nanosleep() 1 ns
|
|
|
|
|
usleep() 1 µs
|
|
|
|
|
delay() 1 µs
|
|
|
|
|
sleep() 1 sec
|
|
|
|
|
======================== ==========
|
|
|
|
|
|
|
|
|
|
Other functions:
|
|
|
|
|
|
|
|
|
|
======================== ==========
|
|
|
|
|
Name Resolution
|
|
|
|
|
======================== ==========
|
|
|
|
|
sigtimedwait() 1 ns
|
|
|
|
|
pthread_cond_timedwait() 1 ns
|
|
|
|
|
sem_timedwait() 1 ns
|
|
|
|
|
select() 1 µs
|
|
|
|
|
epoll() 1 ms
|
|
|
|
|
poll() 1 ms
|
|
|
|
|
WaitForSingleObject() 1 ms
|
|
|
|
|
======================== ==========
|
|
|
|
|
|
2012-04-11 19:22:23 -04:00
|
|
|
|
|
2012-04-13 20:22:50 -04:00
|
|
|
|
Functions
|
|
|
|
|
^^^^^^^^^
|
2012-04-08 19:32:02 -04:00
|
|
|
|
|
|
|
|
|
* sleep(seconds)
|
|
|
|
|
* usleep(microseconds)
|
2012-04-11 19:26:17 -04:00
|
|
|
|
* nanosleep(nanoseconds, remaining):
|
|
|
|
|
`Linux manpage of nanosleep()
|
2012-04-08 19:32:02 -04:00
|
|
|
|
<http://www.kernel.org/doc/man-pages/online/pages/man2/nanosleep.2.html>`_
|
|
|
|
|
* delay(milliseconds)
|
|
|
|
|
|
2012-04-11 19:22:23 -04:00
|
|
|
|
|
2012-04-08 19:32:02 -04:00
|
|
|
|
clock_nanosleep
|
2012-04-13 20:22:50 -04:00
|
|
|
|
^^^^^^^^^^^^^^^
|
2012-04-08 19:32:02 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
clock_nanosleep(clock_id, flags, nanoseconds, remaining): `Linux
|
|
|
|
|
manpage of clock_nanosleep()
|
2012-04-08 19:32:02 -04:00
|
|
|
|
<http://www.kernel.org/doc/man-pages/online/pages/man2/clock_nanosleep.2.html>`_.
|
|
|
|
|
|
|
|
|
|
If flags is TIMER_ABSTIME, then request is interpreted as an absolute
|
|
|
|
|
time as measured by the clock, clock_id. If request is less than or
|
2012-04-12 13:12:48 -04:00
|
|
|
|
equal to the current value of the clock, then clock_nanosleep()
|
|
|
|
|
returns immediately without suspending the calling thread.
|
2012-04-08 19:32:02 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
POSIX.1 specifies that changing the value of the CLOCK_REALTIME clock
|
|
|
|
|
via clock_settime(2) shall have no effect on a thread that is blocked
|
|
|
|
|
on a relative clock_nanosleep().
|
2012-04-08 19:32:02 -04:00
|
|
|
|
|
2012-04-11 19:22:23 -04:00
|
|
|
|
|
2012-04-08 19:32:02 -04:00
|
|
|
|
select()
|
2012-04-13 20:22:50 -04:00
|
|
|
|
^^^^^^^^
|
2012-04-08 19:32:02 -04:00
|
|
|
|
|
|
|
|
|
select(nfds, readfds, writefds, exceptfs, timeout).
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Since Linux 2.6.28, select() uses high-resolution timers to handle the
|
|
|
|
|
timeout. A process has a "slack" attribute to configure the precision
|
|
|
|
|
of the timeout, the default slack is 50 microseconds. Before Linux
|
|
|
|
|
2.6.28, timeouts for select() were handled by the main timing
|
|
|
|
|
subsystem at a jiffy-level resolution. Read also `High- (but not too
|
|
|
|
|
high-) resolution timeouts <http://lwn.net/Articles/296578/>`_ and
|
|
|
|
|
`Timer slack <http://lwn.net/Articles/369549/>`_.
|
2012-04-08 19:32:02 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Other functions
|
2012-04-13 20:22:50 -04:00
|
|
|
|
^^^^^^^^^^^^^^^
|
2012-04-08 19:32:02 -04:00
|
|
|
|
|
|
|
|
|
* poll(), epoll()
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* sigtimedwait(). POSIX: "If the Monotonic Clock option is supported,
|
|
|
|
|
the CLOCK_MONOTONIC clock shall be used to measure the time
|
|
|
|
|
interval specified by the timeout argument."
|
|
|
|
|
* pthread_cond_timedwait(), pthread_condattr_setclock(). "The default
|
|
|
|
|
value of the clock attribute shall refer to the system clock."
|
|
|
|
|
* sem_timedwait(): "If the Timers option is supported, the timeout
|
|
|
|
|
shall be based on the CLOCK_REALTIME clock. If the Timers option is
|
|
|
|
|
not supported, the timeout shall be based on the system clock as
|
2012-04-12 20:16:55 -04:00
|
|
|
|
returned by the time() function. The precision of the timeout
|
|
|
|
|
shall be the precision of the clock on which it is based."
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* WaitForSingleObject(): use the same timer than GetTickCount() with
|
2012-04-12 20:16:55 -04:00
|
|
|
|
the same precision.
|
2012-04-08 19:32:02 -04:00
|
|
|
|
|
|
|
|
|
|
2012-04-13 20:22:50 -04:00
|
|
|
|
System Standby
|
|
|
|
|
==============
|
|
|
|
|
|
|
|
|
|
The ACPI power state "S3" is as system standby mode, also called "Suspend to
|
|
|
|
|
RAM". RAM remains powered.
|
|
|
|
|
|
|
|
|
|
On Windows, the WM_POWERBROADCAST message is send to Windows application
|
|
|
|
|
to notify them of power-management events (ex: ower status has changed).
|
|
|
|
|
|
|
|
|
|
For Mac OS X, read `Registering and unregistering for sleep
|
|
|
|
|
and wake notifications
|
|
|
|
|
<http://developer.apple.com/library/mac/#qa/qa1340/_index.html>`_ (Technical
|
|
|
|
|
Q&A QA1340).
|
|
|
|
|
|
|
|
|
|
|
2012-03-27 13:40:24 -04:00
|
|
|
|
Alternatives: API design
|
|
|
|
|
========================
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-12 07:38:06 -04:00
|
|
|
|
Other names for new functions
|
|
|
|
|
-----------------------------
|
|
|
|
|
|
|
|
|
|
time.monotonic():
|
2012-03-31 22:03:15 -04:00
|
|
|
|
|
2012-04-03 21:47:55 -04:00
|
|
|
|
* time.counter()
|
|
|
|
|
* time.seconds()
|
2012-04-03 20:57:55 -04:00
|
|
|
|
* time.steady()
|
2012-04-03 21:47:55 -04:00
|
|
|
|
* time.timeout_clock()
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* time.wallclock(): it is not the system time aka the "wall clock",
|
|
|
|
|
but a monotonic clock with an unspecified starting point
|
2012-04-03 20:57:55 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
The name "time.try_monotonic()" was also proposed when
|
|
|
|
|
time.monotonic() was falling back to the system clock when no
|
|
|
|
|
monotonic clock was available.
|
2012-03-28 09:02:58 -04:00
|
|
|
|
|
2012-04-12 07:38:06 -04:00
|
|
|
|
time.perf_counter():
|
|
|
|
|
|
|
|
|
|
* time.hires()
|
|
|
|
|
* time.highres()
|
|
|
|
|
* time.timer()
|
|
|
|
|
|
2012-03-27 13:40:24 -04:00
|
|
|
|
|
2012-04-03 19:00:46 -04:00
|
|
|
|
Only expose operating system clocks
|
|
|
|
|
-----------------------------------
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
To not have to define high-level clocks, which is a difficult task, a
|
|
|
|
|
simpler approach is to only expose operating system clocks.
|
|
|
|
|
time.clock_gettime() and related clock identifiers were already added
|
|
|
|
|
to Python 3.3 for example.
|
2012-04-03 19:00:46 -04:00
|
|
|
|
|
|
|
|
|
|
2012-04-03 20:57:55 -04:00
|
|
|
|
Fallback to system clock
|
|
|
|
|
------------------------
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
If no monotonic clock is available, time.monotonic() falls back to the
|
|
|
|
|
system clock.
|
2012-04-03 19:00:46 -04:00
|
|
|
|
|
2012-04-03 20:57:55 -04:00
|
|
|
|
Issues:
|
2012-04-03 19:00:46 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* It is hard to define correctly such function in the documentation:
|
|
|
|
|
is it monotonic? is it steady? is it adjusted?
|
|
|
|
|
* Some user want to decide what to do when no monotonic clock is
|
|
|
|
|
available: use another clock, display an error, or do something
|
|
|
|
|
else?
|
2012-04-03 19:00:46 -04:00
|
|
|
|
|
|
|
|
|
|
2012-04-11 07:06:33 -04:00
|
|
|
|
One function choosing the clock from a list of constraints
|
|
|
|
|
----------------------------------------------------------
|
2012-04-03 19:00:46 -04:00
|
|
|
|
|
2012-04-03 19:49:55 -04:00
|
|
|
|
``time.get_clock(*flags)`` with the following flags:
|
2012-04-03 19:00:46 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* time.MONOTONIC: clock cannot go backward
|
|
|
|
|
* time.STEADY: clock rate is steady and the clock is not adjusted
|
2012-04-12 20:16:55 -04:00
|
|
|
|
* time.HIGHRES: clock with the highest precision
|
2012-04-03 19:00:46 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
time.get_clock() returns None if the clock is found and so calls can
|
|
|
|
|
be chained using the or operator. Example::
|
2012-04-03 19:00:46 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
get_time = time.get_clock(time.MONOTONIC) or time.get_clock(time.STEADY) or time.time()
|
|
|
|
|
t = get_time()
|
2012-04-03 19:00:46 -04:00
|
|
|
|
|
|
|
|
|
Example of flags of system clocks:
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* QueryPerformanceCounter: MONOTONIC | HIGHRES
|
|
|
|
|
* GetTickCount: MONOTONIC | STEADY
|
|
|
|
|
* CLOCK_MONOTONIC: MONOTONIC | STEADY (or only MONOTONIC on Linux)
|
|
|
|
|
* CLOCK_MONOTONIC_RAW: MONOTONIC | STEADY
|
|
|
|
|
* gettimeofday(): (no flag)
|
2012-04-03 19:00:46 -04:00
|
|
|
|
|
|
|
|
|
|
2012-03-31 22:23:32 -04:00
|
|
|
|
One function with a flag: time.monotonic(fallback=True)
|
|
|
|
|
-------------------------------------------------------
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* time.monotonic(fallback=True) falls back to the system clock if no
|
|
|
|
|
monotonic clock is available or if the monotonic clock failed.
|
|
|
|
|
* time.monotonic(fallback=False) raises OSError if monotonic clock
|
|
|
|
|
fails and NotImplementedError if the system does not provide a
|
|
|
|
|
monotonic clock
|
2012-03-31 22:23:32 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
"A keyword argument that gets passed as a constant in the caller is
|
|
|
|
|
usually poor API."
|
2012-03-31 22:23:32 -04:00
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
Raising NotImplementedError for a function is something uncommon in
|
|
|
|
|
Python and should be avoided.
|
2012-03-31 22:23:32 -04:00
|
|
|
|
|
|
|
|
|
|
2012-03-26 19:12:03 -04:00
|
|
|
|
One function, no flag
|
|
|
|
|
---------------------
|
|
|
|
|
|
2012-03-27 20:18:11 -04:00
|
|
|
|
time.monotonic() returns (time: float, is_monotonic: bool).
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
An alternative is to use a function attribute:
|
|
|
|
|
time.monotonic.is_monotonic. The attribute value would be None before
|
|
|
|
|
the first call to time.monotonic().
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
|
|
|
|
|
2012-03-26 19:30:38 -04:00
|
|
|
|
Working around operating system bugs?
|
|
|
|
|
=====================================
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
Should Python ensure manually that a monotonic clock is truly
|
|
|
|
|
monotonic by computing the maximum with the clock value and the
|
|
|
|
|
previous value?
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
Since it's relatively straightforward to cache the last value returned
|
|
|
|
|
using a static variable, it might be interesting to use this to make
|
|
|
|
|
sure that the values returned are indeed monotonic.
|
2012-03-28 09:02:58 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* Virtual machines provide less reliable clocks.
|
|
|
|
|
* QueryPerformanceCounter() has known bugs (only one is not fixed yet)
|
2012-03-28 19:11:16 -04:00
|
|
|
|
|
2012-03-31 02:53:07 -04:00
|
|
|
|
Python may only work around a specific known operating system bug:
|
2012-03-31 02:38:41 -04:00
|
|
|
|
`KB274323`_ contains a code example to workaround the bug (use
|
|
|
|
|
GetTickCount() to detect QueryPerformanceCounter() leap).
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-04-03 19:57:37 -04:00
|
|
|
|
Issues of a hacked monotonic function:
|
|
|
|
|
|
2012-04-12 13:12:48 -04:00
|
|
|
|
* if the clock is accidentally set forward by an hour and then back
|
|
|
|
|
again, you wouldn't have a useful clock for an hour
|
|
|
|
|
* the cache is not shared between processes so different processes
|
|
|
|
|
wouldn't see the same clock value
|
2012-04-03 19:57:37 -04:00
|
|
|
|
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-03-27 19:57:37 -04:00
|
|
|
|
Footnotes
|
|
|
|
|
=========
|
|
|
|
|
|
2012-03-28 09:02:58 -04:00
|
|
|
|
.. [#pseudo] "_time" is an hypothetical module only used for the example.
|
2012-03-31 02:38:41 -04:00
|
|
|
|
The time module is implemented in C and so there is no need for
|
|
|
|
|
such module.
|
2012-03-27 19:57:37 -04:00
|
|
|
|
|
|
|
|
|
|
2012-03-26 19:12:03 -04:00
|
|
|
|
Links
|
|
|
|
|
=====
|
|
|
|
|
|
2012-03-28 18:57:15 -04:00
|
|
|
|
Related Python issues:
|
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* `Issue #12822: NewGIL should use CLOCK_MONOTONIC if possible.
|
|
|
|
|
<http://bugs.python.org/issue12822>`_
|
|
|
|
|
* `Issue #14222: Use time.steady() to implement timeout
|
|
|
|
|
<http://bugs.python.org/issue14222>`_
|
2012-04-11 07:06:33 -04:00
|
|
|
|
* `Issue #14309: Deprecate time.clock()
|
|
|
|
|
<http://bugs.python.org/issue14309>`_
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* `Issue #14397: Use GetTickCount/GetTickCount64 instead of
|
|
|
|
|
QueryPerformanceCounter for monotonic clock
|
|
|
|
|
<http://bugs.python.org/issue14397>`_
|
|
|
|
|
* `Issue #14428: Implementation of the PEP 418
|
|
|
|
|
<http://bugs.python.org/issue14428>`_
|
2012-04-11 18:34:32 -04:00
|
|
|
|
* `Issue #14555: clock_gettime/settime/getres: Add more clock identifiers
|
|
|
|
|
<http://bugs.python.org/issue14555>`_
|
2012-03-31 02:38:41 -04:00
|
|
|
|
|
|
|
|
|
Libraries exposing monotonic clocks:
|
|
|
|
|
|
|
|
|
|
* `Java: System.nanoTime
|
|
|
|
|
<http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#nanoTime()>`_
|
|
|
|
|
* `Qt library: QElapsedTimer
|
|
|
|
|
<http://qt-project.org/doc/qt-4.8/qelapsedtimer.html>`_
|
|
|
|
|
* `glib library: g_get_monotonic_time ()
|
|
|
|
|
<http://developer.gnome.org/glib/2.30/glib-Date-and-Time-Functions.html#g-get-monotonic-time>`_
|
|
|
|
|
uses GetTickCount64()/GetTickCount() on Windows,
|
|
|
|
|
clock_gettime(CLOCK_MONOTONIC) on UNIX or falls back to the system
|
|
|
|
|
clock
|
|
|
|
|
* `python-monotonic-time
|
|
|
|
|
<http://code.google.com/p/python-monotonic-time/>`_ (`github
|
|
|
|
|
<https://github.com/gavinbeatty/python-monotonic-time>`_)
|
2012-04-04 18:38:51 -04:00
|
|
|
|
* `Monoclock.nano_count()
|
|
|
|
|
<https://github.com/ludios/Monoclock>`_ uses clock_gettime(CLOCK_MONOTONIC)
|
|
|
|
|
and returns a number of nanoseconds
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* `monotonic_clock <https://github.com/ThomasHabets/monotonic_clock>`_
|
|
|
|
|
* `Perl: Time::HiRes <http://perldoc.perl.org/Time/HiRes.html>`_
|
|
|
|
|
exposes clock_gettime(CLOCK_MONOTONIC)
|
|
|
|
|
* `Ruby: AbsoluteTime.now
|
|
|
|
|
<https://github.com/bwbuchanan/absolute_time/>`_: use
|
|
|
|
|
clock_gettime(CLOCK_MONOTONIC), mach_absolute_time() or
|
|
|
|
|
gettimeofday(). "AbsoluteTime.monotonic?" method indicates if
|
|
|
|
|
AbsoluteTime.now is monotonic or not.
|
2012-04-02 15:52:32 -04:00
|
|
|
|
* `libpthread
|
|
|
|
|
<http://code.google.com/p/libpthread/>`_: POSIX thread library for Windows
|
|
|
|
|
(`clock.c <http://code.google.com/p/libpthread/source/browse/src/clock.c>`_)
|
2012-04-04 07:26:35 -04:00
|
|
|
|
* `Boost.Chrono
|
|
|
|
|
<http://www.boost.org/doc/libs/1_49_0/doc/html/chrono.html>`_ uses:
|
|
|
|
|
|
|
|
|
|
* system_clock:
|
|
|
|
|
|
|
|
|
|
* mac = gettimeofday()
|
|
|
|
|
* posix = clock_gettime(CLOCK_REALTIME)
|
|
|
|
|
* win = GetSystemTimeAsFileTime()
|
|
|
|
|
|
|
|
|
|
* steady_clock:
|
|
|
|
|
|
|
|
|
|
* mac = mach_absolute_time()
|
|
|
|
|
* posix = clock_gettime(CLOCK_MONOTONIC)
|
|
|
|
|
* win = QueryPerformanceCounter()
|
|
|
|
|
|
|
|
|
|
* high_resolution_clock:
|
|
|
|
|
|
|
|
|
|
* steady_clock, if available system_clock, otherwise
|
2012-03-28 18:57:15 -04:00
|
|
|
|
|
2012-03-29 21:41:03 -04:00
|
|
|
|
Time:
|
2012-03-28 18:57:15 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
* `hrtimers - subsystem for high-resolution kernel timers
|
|
|
|
|
<http://www.kernel.org/doc/Documentation/timers/hrtimers.txt>`_
|
|
|
|
|
* `C++ Timeout Specification
|
|
|
|
|
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3128.html>`_
|
|
|
|
|
* `Windows: Game Timing and Multicore Processors
|
|
|
|
|
<http://msdn.microsoft.com/en-us/library/ee417693.aspx>`_
|
|
|
|
|
* `Implement a Continuously Updating, High-Resolution Time Provider
|
|
|
|
|
for Windows
|
|
|
|
|
<http://msdn.microsoft.com/en-us/magazine/cc163996.aspx>`_
|
|
|
|
|
* `clockspeed <http://cr.yp.to/clockspeed.html>`_ uses a hardware tick
|
|
|
|
|
counter to compensate for a persistently fast or slow system clock
|
|
|
|
|
* `Retrieving system time
|
|
|
|
|
<http://en.wikipedia.org/wiki/System_time#Retrieving_system_time>`_
|
|
|
|
|
lists hardware clocks and time functions with their resolution and
|
|
|
|
|
epoch or range
|
|
|
|
|
* On Windows, the JavaScript runtime of Firefox interpolates
|
|
|
|
|
GetSystemTimeAsFileTime() with QueryPerformanceCounter() to get an
|
|
|
|
|
higher resolution. See the `Bug 363258 - bad millisecond resolution
|
|
|
|
|
for (new Date).getTime() / Date.now() on Windows
|
|
|
|
|
<https://bugzilla.mozilla.org/show_bug.cgi?id=363258>`_.
|
|
|
|
|
* `When microseconds matter
|
|
|
|
|
<http://www.ibm.com/developerworks/library/i-seconds/>`_: How the
|
|
|
|
|
IBM High Resolution Time Stamp Facility accurately measures itty
|
|
|
|
|
bits of time
|
2012-04-04 18:38:51 -04:00
|
|
|
|
* `Win32 Performance Measurement Options
|
|
|
|
|
<http://drdobbs.com/windows/184416651>`_ by Matthew Wilson, May 01, 2003
|
2012-04-11 18:19:16 -04:00
|
|
|
|
* `Counter Availability and Characteristics for Feed-forward Based Synchronization
|
|
|
|
|
<http://www.cubinlab.ee.unimelb.edu.au/~jrid/Publications/ridoux_ispcs09.pdf>`_
|
|
|
|
|
by Timothy Broomhead, Julien Ridoux, Darryl Veitch (2009)
|
2012-04-11 08:04:23 -04:00
|
|
|
|
* System Management Interrupt (SMI) issues:
|
|
|
|
|
|
|
|
|
|
* `System Management Interrupt Free Hardware
|
|
|
|
|
<http://linuxplumbersconf.org/2009/slides/Keith-Mannthey-SMI-plumers-2009.pdf>`_
|
|
|
|
|
(Keith Mannthey, 2009)
|
|
|
|
|
* `IBM Real-Time "SMI Free" mode driver
|
|
|
|
|
<http://lwn.net/Articles/318725/>`_
|
|
|
|
|
* `Fixing Realtime problems caused by SMI on Ubuntu
|
|
|
|
|
<http://wiki.linuxcnc.org/cgi-bin/wiki.pl?FixingSMIIssues>`_
|
|
|
|
|
* `[RFC] simple SMI detector
|
|
|
|
|
<http://lwn.net/Articles/316622/>`_
|
|
|
|
|
* `[PATCH 2.6.34-rc3] A nonintrusive SMI sniffer for x86.
|
|
|
|
|
<http://marc.info/?l=linux-kernel&m=127058720921201&w=1>`_
|
2012-03-31 02:38:41 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Copyright
|
|
|
|
|
=========
|
|
|
|
|
|
|
|
|
|
This document has been placed in the public domain.
|
|
|
|
|
|
2012-03-26 19:12:03 -04:00
|
|
|
|
|
2012-03-31 02:38:41 -04:00
|
|
|
|
|
|
|
|
|
..
|
|
|
|
|
Local Variables:
|
|
|
|
|
mode: indented-text
|
|
|
|
|
indent-tabs-mode: nil
|
|
|
|
|
sentence-end-double-space: t
|
|
|
|
|
fill-column: 70
|
|
|
|
|
coding: utf-8
|
|
|
|
|
End:
|