Edit PEP 418: add missing copyright and file variable footer, fix line length and indentation of bullet lists, fix grammar and spelling
This commit is contained in:
parent
72a7239f0e
commit
2534727122
610
pep-0418.txt
610
pep-0418.txt
|
@ -13,7 +13,8 @@ Python-Version: 3.3
|
|||
Abstract
|
||||
========
|
||||
|
||||
Add time.monotonic(fallback=True) and time.highres() functions to Python 3.3.
|
||||
Add time.monotonic(fallback=True) and time.highres() functions to
|
||||
Python 3.3.
|
||||
|
||||
|
||||
Rationale
|
||||
|
@ -21,32 +22,34 @@ Rationale
|
|||
|
||||
Use cases:
|
||||
|
||||
* Display the current time to a human (e.g. display a calendar or draw a wall
|
||||
clock): use system clock. time.time() or datetime.datetime.now()
|
||||
* Benchmark, profiling, timeout: time.highres()
|
||||
* Event scheduler: time.monotonic(), or time.monotonic(fallback=False)
|
||||
* Display the current time to a human (e.g. display a calendar or draw
|
||||
a wall clock): use system clock. time.time() or
|
||||
datetime.datetime.now()
|
||||
* Benchmark, profiling, timeout: time.highres()
|
||||
* Event scheduler: time.monotonic(), or time.monotonic(fallback=False)
|
||||
|
||||
|
||||
Functions
|
||||
=========
|
||||
|
||||
* time.time(): system clock, "wall clock"
|
||||
* time.highres(): clock with the best accuracy
|
||||
* time.monotonic(fallback=True): monotonic clock. If no monotonic clock is
|
||||
available, falls back to system clock by default, or raises an OSError if
|
||||
*fallback* is False. time.monotonic(fallback=True) cannot go backward.
|
||||
* time.time(): system clock, "wall clock"
|
||||
* time.highres(): clock with the best accuracy
|
||||
* time.monotonic(fallback=True): monotonic clock. If no monotonic
|
||||
clock is available, falls back to system clock by default, or raises
|
||||
an OSError if *fallback* is False. time.monotonic(fallback=True)
|
||||
cannot go backward.
|
||||
|
||||
|
||||
time.time()
|
||||
-----------
|
||||
|
||||
The system time is the "wall clock". It can be set manually by the system
|
||||
administrator or automatically by a NTP daemon. It can jump backward and
|
||||
forward. It is not monotonic.
|
||||
The system time is the "wall clock". It can be set manually by the
|
||||
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]_: ::
|
||||
Pseudo-code [#pseudo]_::
|
||||
|
||||
if os.name == "nt":
|
||||
def time():
|
||||
|
@ -78,20 +81,21 @@ Pseudo-code [#pseudo]_: ::
|
|||
time.monotonic(fallback=True)
|
||||
-----------------------------
|
||||
|
||||
Clock that cannot go backward, its rate is as steady as possible. Its rate may
|
||||
be adjusted by NTP. The reference point of the returned value is undefined so
|
||||
only the difference of consecutive calls is valid.
|
||||
Clock that cannot go backward, its rate is as steady as possible. Its
|
||||
rate may be adjusted by NTP. The reference point of the returned
|
||||
value is undefined so only the difference of consecutive calls is
|
||||
valid.
|
||||
|
||||
By default, it falls back to the system clock if no monotonic clock is
|
||||
available or if the monotonic clock failed, and so it cannot fail. If fallback
|
||||
is False, it raises OSError if the monotonic clock failed and
|
||||
NotImplementedError if the platform does not provide a monotonic clock (ex:
|
||||
GNU/Hurd).
|
||||
available or if the monotonic clock failed, and so it cannot fail. If
|
||||
fallback is False, it raises OSError if the monotonic clock failed and
|
||||
NotImplementedError if the platform does not provide a monotonic clock
|
||||
(ex: GNU/Hurd).
|
||||
|
||||
The elapsed time may or may not include time the system spends in sleep or
|
||||
hibernation, it depends on the operating system.
|
||||
The elapsed time may or may not include time the system spends in
|
||||
sleep or hibernation, it depends on the operating system.
|
||||
|
||||
Pseudo-code [#pseudo]_: ::
|
||||
Pseudo-code [#pseudo]_::
|
||||
|
||||
if os.name == 'nt':
|
||||
# GetTickCount64() requires Windows Vista, Server 2008 or later
|
||||
|
@ -161,15 +165,17 @@ Pseudo-code [#pseudo]_: ::
|
|||
raise NotImplementedError("you platform does not provide any monotonic clock")
|
||||
return time.time()
|
||||
|
||||
On Windows, QueryPerformanceCounter() is not used even if it has a better
|
||||
resolution than GetTickCount(). It is not reliable and has too much issues.
|
||||
On Windows, QueryPerformanceCounter() is not used even if it has a
|
||||
better resolution than GetTickCount(). It is not reliable and has too
|
||||
much issues.
|
||||
|
||||
.. note::
|
||||
|
||||
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
|
||||
time.monotonic() value may be different in two Python processes.
|
||||
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 time.monotonic() value may be different
|
||||
in two Python processes.
|
||||
|
||||
|
||||
time.highres()
|
||||
|
@ -220,35 +226,35 @@ GetTickCount[64]() 1 ms 1 ms - 15 ms No Inclu
|
|||
timeGetTime() 1 ms 1 ms - 15 ms No ?
|
||||
========================= =============== =============== ================ ====================
|
||||
|
||||
(*) The accurary of monotonic clocks depends on the operating system and the
|
||||
hardware clock.
|
||||
(*) The accuracy of monotonic clocks depends on the operating system
|
||||
and the hardware clock.
|
||||
|
||||
The resolution is the smallest difference between two timestamps supported by
|
||||
the format used by the clock. For example, clock_gettime() uses a timespec
|
||||
structure which has two integer fileds, tv_sec and tv_nsec, so the resolution
|
||||
is 1 nanosecond.
|
||||
The resolution is the smallest difference between two timestamps
|
||||
supported by the format used by the clock. For example,
|
||||
clock_gettime() uses a timespec structure which has two integer
|
||||
fields, tv_sec and tv_nsec, so the resolution is 1 nanosecond.
|
||||
|
||||
The accuracy is the effective smallest difference of two timestamps of the
|
||||
clock. It does not reflect the stability the clock rate. For example,
|
||||
QueryPerformanceCounter() has a good accuracy but is known to not have a steady
|
||||
rate.
|
||||
The accuracy is the effective smallest difference of two timestamps of
|
||||
the clock. It does not reflect the stability the clock rate. For
|
||||
example, QueryPerformanceCounter() has a good accuracy but is known to
|
||||
not have a steady rate.
|
||||
|
||||
|
||||
mach_absolute_time
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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/>`_), mach_timebase_info()
|
||||
is always equals to one and does never fail, even if the function may fail
|
||||
according to its prototype.
|
||||
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/>`_),
|
||||
mach_timebase_info() is always equals to one and does never fail, even
|
||||
if the function may fail according to its prototype.
|
||||
|
||||
mach_absolute_time() stops during a sleep on PowerPC CPU, but not on Intel CPU:
|
||||
`Different behaviour of mach_absolute_time() on i386 / ppc
|
||||
mach_absolute_time() stops during a sleep on PowerPC CPU, but not on
|
||||
Intel CPU: `Different behaviour of mach_absolute_time() on i386 / ppc
|
||||
<http://lists.apple.com/archives/PerfOptimization-dev/2006/Jul/msg00024.html>`_.
|
||||
|
||||
mach_absolute_time() has a resolution of 1 nanosecond.
|
||||
|
@ -256,95 +262,104 @@ mach_absolute_time() has a resolution of 1 nanosecond.
|
|||
CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
CLOCK_MONOTONIC and CLOCK_MONOTONIC_RAW represents monotonic time since some
|
||||
unspecified starting point. They cannot be set.
|
||||
CLOCK_MONOTONIC and CLOCK_MONOTONIC_RAW represents monotonic time
|
||||
since some unspecified starting point. They cannot be set.
|
||||
|
||||
Documentation: refer to the manual page of your operating system. Examples:
|
||||
Documentation: refer to the manual page of your operating system.
|
||||
Examples:
|
||||
|
||||
* `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>`_
|
||||
* `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>`_
|
||||
|
||||
CLOCK_MONOTONIC is available at least on the following operating systems:
|
||||
|
||||
* DragonFly BSD, FreeBSD >= 5.0, OpenBSD, NetBSD
|
||||
* Linux
|
||||
* Solaris
|
||||
* DragonFly BSD, FreeBSD >= 5.0, OpenBSD, NetBSD
|
||||
* Linux
|
||||
* Solaris
|
||||
|
||||
The following operating systems don't support CLOCK_MONOTONIC:
|
||||
|
||||
* GNU/Hurd (see `open issues/ clock_gettime
|
||||
<http://www.gnu.org/software/hurd/open_issues/clock_gettime.html>`_)
|
||||
* Mac OS X
|
||||
* Windows
|
||||
|
||||
* GNU/Hurd (see `open issues/ clock_gettime <http://www.gnu.org/software/hurd/open_issues/clock_gettime.html>`_)
|
||||
* Mac OS X
|
||||
* Windows
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
On Linux, NTP may adjust CLOCK_MONOTONIC rate, but not jump backward. If
|
||||
available, CLOCK_MONOTONIC_RAW should be used instead of CLOCK_MONOTONIC to
|
||||
avoid the NTP adjustement.
|
||||
On Linux, NTP may adjust CLOCK_MONOTONIC rate, but not jump backward.
|
||||
If available, CLOCK_MONOTONIC_RAW should be used instead of
|
||||
CLOCK_MONOTONIC to avoid the NTP adjustment.
|
||||
|
||||
CLOCK_MONOTONIC stops while the machine is suspended.
|
||||
|
||||
clock_gettime() fails if the system does not support the specified clock,
|
||||
whereas the standard C library supports it. For example, CLOCK_MONOTONIC_RAW
|
||||
requires a kernel version 2.6.28 or later.
|
||||
clock_gettime() fails if the system does not support the specified
|
||||
clock, whereas the standard C library supports it. For example,
|
||||
CLOCK_MONOTONIC_RAW requires a kernel version 2.6.28 or later.
|
||||
|
||||
clock_getres() gives the clock resolution. It is 1 nanosecond on Linux.
|
||||
clock_getres() gives the clock resolution. It is 1 nanosecond on
|
||||
Linux.
|
||||
|
||||
.. note::
|
||||
clock_gettime() requires to link the program to the rt (real-time) library.
|
||||
clock_gettime() requires to link the program to the rt (real-time)
|
||||
library.
|
||||
|
||||
|
||||
Windows: QueryPerformanceCounter
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
High-resolution performance counter. It is monotonic.
|
||||
High-resolution performance counter. It is monotonic.
|
||||
QueryPerformanceFrequency() gives its frequency.
|
||||
|
||||
It has much higher resolution, but has lower long term accuracy than
|
||||
GetTickCount() and timeGetTime() clocks. For example, it will drift compared to
|
||||
the low precision clocks.
|
||||
GetTickCount() and timeGetTime() clocks. For example, it will drift
|
||||
compared to the low precision clocks.
|
||||
|
||||
Documentation:
|
||||
|
||||
* `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>`_
|
||||
* `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>`_
|
||||
|
||||
Hardware clocks used by QueryPerformanceCounter:
|
||||
|
||||
* Windows XP: RDTSC instruction of Intel processors, the clock frequency is
|
||||
the frequency of the processor (between 200 MHz and 3 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
|
||||
* Windows 95/98: 8245 PIT chipset, frequency = 1,193,181 Hz
|
||||
* Windows XP: RDTSC instruction of Intel processors, the clock
|
||||
frequency is the frequency of the processor (between 200 MHz and 3
|
||||
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
|
||||
|
||||
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.
|
||||
.. * Windows 95/98: 8245 PIT chipset, frequency = 1,193,181 Hz
|
||||
|
||||
QueryPerformanceCounter() cannot be adjusted: `SetSystemTimeAdjustment()
|
||||
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.
|
||||
|
||||
QueryPerformanceCounter() cannot be adjusted:
|
||||
`SetSystemTimeAdjustment()
|
||||
<http://msdn.microsoft.com/en-us/library/windows/desktop/ms724943(v=vs.85).aspx>`_
|
||||
does only adjust the system time.
|
||||
|
||||
Bugs:
|
||||
|
||||
* The performance counter value may unexpectedly leap forward because of a
|
||||
hardware bug, see the `KB274323`_.
|
||||
* 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.
|
||||
* The performance counter value may unexpectedly leap forward because
|
||||
of a hardware bug, see the `KB274323`_.
|
||||
* 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.
|
||||
|
||||
.. _KB896256: http://support.microsoft.com/?id=896256
|
||||
.. _KB274323: http://support.microsoft.com/?id=274323
|
||||
|
@ -353,18 +368,20 @@ Bugs:
|
|||
Windows: GetTickCount(), GetTickCount64()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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>`_.
|
||||
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>`_.
|
||||
|
||||
The elapsed time retrieved by GetTickCount or GetTickCount64 includes time the
|
||||
system spends in sleep or hibernation.
|
||||
The elapsed time retrieved by GetTickCount or GetTickCount64 includes
|
||||
time the system spends in sleep or hibernation.
|
||||
|
||||
GetTickCount64() was added to Windows Vista and Windows Server 2008.
|
||||
|
||||
The clock resolution is 1 millisecond. Its accuracy is usually around 15 ms. It
|
||||
is possible to improve the accuracy using the `undocumented
|
||||
The clock resolution is 1 millisecond. Its accuracy is usually around
|
||||
15 ms. It is possible to improve the accuracy using the `undocumented
|
||||
NtSetTimerResolution() function
|
||||
<http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Time/NtSetTimerResolution.html>`_.
|
||||
There are applications using this undocumented function, example:
|
||||
|
@ -374,47 +391,50 @@ There are applications using this undocumented function, example:
|
|||
Windows: timeGetTime
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The timeGetTime function retrieves the system time, in milliseconds. The system
|
||||
time is the time elapsed since Windows was started. Read the `timeGetTime()
|
||||
documentation
|
||||
The timeGetTime function retrieves the system time, in milliseconds.
|
||||
The system time is the time elapsed since Windows was started. Read
|
||||
the `timeGetTime() documentation
|
||||
<http://msdn.microsoft.com/en-us/library/windows/desktop/dd757629(v=vs.85).aspx>`_.
|
||||
|
||||
The return type of timeGetTime() is a 32-bit unsigned integer. As
|
||||
GetTickCount(), timeGetTime() rolls over after 2^32 milliseconds (49.7 days).
|
||||
The return type of timeGetTime() is a 32-bit unsigned integer. As
|
||||
GetTickCount(), timeGetTime() rolls over after 2^32 milliseconds (49.7
|
||||
days).
|
||||
|
||||
The default precision of the timeGetTime function can be five milliseconds or
|
||||
more, depending on the machine.
|
||||
The default precision of the timeGetTime function can be five
|
||||
milliseconds or more, depending on the machine.
|
||||
|
||||
timeBeginPeriod() can be used to increase the precision of timeGetTime() up to
|
||||
1 millisecond, but it negatively affects power consumption.
|
||||
timeBeginPeriod() can be used to increase the precision of
|
||||
timeGetTime() up to 1 millisecond, but it negatively affects power
|
||||
consumption.
|
||||
|
||||
.. note::
|
||||
timeGetTime() and timeBeginPeriod() are part the Windows multimedia library
|
||||
and so require to link the program with winmm or to load dynamically the
|
||||
library.
|
||||
timeGetTime() and timeBeginPeriod() are part the Windows multimedia
|
||||
library and so require to link the program with winmm or to load
|
||||
dynamically the library.
|
||||
|
||||
|
||||
Solaris: CLOCK_HIGHRES
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The Solaris OS has an CLOCK_HIGHRES timer that attempts to use an 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.
|
||||
The Solaris OS has an CLOCK_HIGHRES timer that attempts to use an
|
||||
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.
|
||||
|
||||
Solaris: gethrtime
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
The linearity of gethrtime() is not preserved accross cpr suspend-resume cycle
|
||||
(`Bug 4272663 <http://wesunsolve.net/bugid/id/4272663>`_).
|
||||
The linearity of gethrtime() is not preserved accross cpr
|
||||
suspend-resume cycle (`Bug 4272663
|
||||
<http://wesunsolve.net/bugid/id/4272663>`_).
|
||||
|
||||
Read the `gethrtime() manual page of Solaris 11
|
||||
<http://docs.oracle.com/cd/E23824_01/html/821-1465/gethrtime-3c.html#scrolltoc>`_.
|
||||
|
@ -435,80 +455,87 @@ ftime() 1 ms (*)
|
|||
time() 1 sec 1 sec
|
||||
========================= =============== ===============
|
||||
|
||||
(*) The accurary of system clocks depends on the operating system and the
|
||||
hardware clock. On Windows, the accuracy is in the range 1 ms - 15 ms.
|
||||
(*) The accuracy of system clocks depends on the operating system and
|
||||
the hardware clock. On Windows, the accuracy is in the range 1 ms -
|
||||
15 ms.
|
||||
|
||||
|
||||
Windows: GetSystemTimeAsFileTime
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The system time can be read using GetSystemTimeAsFileTime(), ftime() and
|
||||
time().
|
||||
The system time can be read using GetSystemTimeAsFileTime(), ftime()
|
||||
and time().
|
||||
|
||||
The system time resolution can be read using GetSystemTimeAdjustment(). The
|
||||
accurary is usually between 1 millisecond and 15 milliseconds. Resolution:
|
||||
The system time resolution can be read using
|
||||
GetSystemTimeAdjustment(). The accuracy is usually between 1
|
||||
millisecond and 15 milliseconds. Resolution:
|
||||
|
||||
* GetSystemTimeAsFileTime(): 100 nanoseconds
|
||||
* ftime(): 1 millisecond
|
||||
* time(): 1 second
|
||||
* GetSystemTimeAsFileTime(): 100 nanoseconds
|
||||
* ftime(): 1 millisecond
|
||||
* time(): 1 second
|
||||
|
||||
The system time can be set using SetSystemTime().
|
||||
|
||||
System time on UNIX
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
gettimeofday(), ftime(), time() and clock_gettime(CLOCK_REALTIME) return the
|
||||
system clock.
|
||||
gettimeofday(), ftime(), time() and clock_gettime(CLOCK_REALTIME)
|
||||
return the system clock.
|
||||
|
||||
Resolution:
|
||||
|
||||
* clock_gettime(): clock_getres(CLOCK_REALTIME), 1 nanosecond on Linux
|
||||
* gettimeofday(): 1 microsecond
|
||||
* ftime(): 1 millisecond
|
||||
* time(): 1 second
|
||||
* clock_gettime(): clock_getres(CLOCK_REALTIME), 1 nanosecond on Linux
|
||||
* gettimeofday(): 1 microsecond
|
||||
* ftime(): 1 millisecond
|
||||
* time(): 1 second
|
||||
|
||||
The system time can be set using settimeofday() or clock_settime(CLOCK_REALTIME).
|
||||
The system time can be set using settimeofday() or
|
||||
clock_settime(CLOCK_REALTIME).
|
||||
|
||||
|
||||
Process and thread time
|
||||
-----------------------
|
||||
|
||||
The process and thread time cannot be set. They are not monotonic: the clocks
|
||||
stop while the process/thread is idle.
|
||||
The process and thread time cannot be set. They are not monotonic:
|
||||
the clocks stop while the process/thread is idle.
|
||||
|
||||
Process
|
||||
^^^^^^^
|
||||
|
||||
* Windows: GetProcessTimes()
|
||||
* clock_gettime(CLOCK_PROCESS_CPUTIME_ID): High-resolution per-process timer
|
||||
from the CPU.
|
||||
* clock():
|
||||
* Windows: GetProcessTimes()
|
||||
* clock_gettime(CLOCK_PROCESS_CPUTIME_ID): High-resolution per-process
|
||||
timer from the CPU.
|
||||
* clock():
|
||||
|
||||
* Windows: The elapsed wall-clock time since the start of the process
|
||||
(elapsed time in seconds times CLOCKS_PER_SEC). It can fail.
|
||||
* UNIX: returns an approximation of processor time used by the program.
|
||||
* Windows: The elapsed wall-clock time since the start of the
|
||||
process (elapsed time in seconds times CLOCKS_PER_SEC). It can
|
||||
fail.
|
||||
* UNIX: returns an approximation of processor time used by the
|
||||
program.
|
||||
|
||||
* times()
|
||||
* getrusage(): ru_utime and ru_stime fields
|
||||
* times()
|
||||
* getrusage(): ru_utime and ru_stime fields
|
||||
|
||||
Resolution:
|
||||
|
||||
* clock() rate is CLOCKS_PER_SEC. It was called CLK_TCK in Microsoft C before
|
||||
6.0. On Linux 3, clock() has a resolution of 1 microsecond
|
||||
* The clock resolution can be read using clock_getres().
|
||||
clock_getres(CLOCK_REALTIME) is 1 nanosecond on Linux
|
||||
* GetProcessTimes(): call GetSystemTimeAdjustment()
|
||||
* clock() rate is CLOCKS_PER_SEC. It was called CLK_TCK in Microsoft
|
||||
C before 6.0. On Linux 3, clock() has a resolution of 1 microsecond
|
||||
* The clock resolution can be read using clock_getres().
|
||||
clock_getres(CLOCK_REALTIME) is 1 nanosecond on Linux
|
||||
* GetProcessTimes(): call GetSystemTimeAdjustment()
|
||||
|
||||
Thread
|
||||
^^^^^^
|
||||
|
||||
* Windows: GetThreadTimes()
|
||||
* clock_gettime(CLOCK_THREAD_CPUTIME_ID): Thread-specific CPU-time clock.
|
||||
* Windows: GetThreadTimes()
|
||||
* clock_gettime(CLOCK_THREAD_CPUTIME_ID): Thread-specific CPU-time
|
||||
clock.
|
||||
|
||||
Resolution:
|
||||
|
||||
* CLOCK_THREAD_CPUTIME_ID: call clock_getres(). 1 nanosecond on Linux.
|
||||
* GetThreadTimes(): call GetSystemTimeAdjustment()
|
||||
* CLOCK_THREAD_CPUTIME_ID: call clock_getres(). 1 nanosecond on
|
||||
Linux.
|
||||
* GetThreadTimes(): call GetSystemTimeAdjustment()
|
||||
|
||||
See also pthread_getcpuclockid().
|
||||
|
||||
|
@ -516,12 +543,12 @@ See also pthread_getcpuclockid().
|
|||
Windows: QueryUnbiasedInterruptTime
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
The elapsed time retrieved by the QueryUnbiasedInterruptTime function includes
|
||||
only time that the system spends in the working state.
|
||||
The elapsed time retrieved by the QueryUnbiasedInterruptTime function
|
||||
includes only time that the system spends in the working state.
|
||||
QueryUnbiasedInterruptTime() is not monotonic.
|
||||
|
||||
QueryUnbiasedInterruptTime() was introduced in Windows 7.
|
||||
|
@ -529,41 +556,43 @@ QueryUnbiasedInterruptTime() was introduced in Windows 7.
|
|||
Linux timers
|
||||
------------
|
||||
|
||||
There were 4 implementations of the time in the Linux kernel: UTIME (1996),
|
||||
timer wheel (1997), HRT (2001) and hrtimers (2007). The later is the result of
|
||||
the "high-res-timers" project started by George Anzinger in 2001, contributed
|
||||
by Thomas Gleixner and Douglas Niehaus. hrtimers implementation was merged into
|
||||
Linux 2.6.21 released in 2007.
|
||||
There were 4 implementations of the time in the Linux kernel: UTIME
|
||||
(1996), timer wheel (1997), HRT (2001) and hrtimers (2007). The later
|
||||
is the result of the "high-res-timers" project started by George
|
||||
Anzinger in 2001, contributed 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.
|
||||
hrtimers supports various clock sources. It sets a priority to each
|
||||
source to decide which one will be used.
|
||||
|
||||
* TSC (Time Stamp Counter): Internal processor clock incremented at each
|
||||
processor cycle. Its frequency is the processor frequency and so usually
|
||||
higher than 1 GHz. Its priority is 300 by default, but falls to 0 if the
|
||||
processor frequency changes and the counter becomes unstable.
|
||||
* HPET: An 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.
|
||||
* PIT (programmable interrupt timer): Intel 8253/8254 chipsets with a
|
||||
configurable frequecency in range 18.2 Hz - 1.2 MHz. Linux uses the
|
||||
frequency: 1,193,181.8 Hz. It is a 16-bit counter.
|
||||
* PMTMR (power management timer): ACPI 24-bit timer with a frequency of 3.5
|
||||
MHz (3,579,545 Hz). Its priority is 200 by default, but changes to 110 if
|
||||
the chipset is broken and need a software workaround. HPET can cause around
|
||||
3 seconds of drift per day.
|
||||
* 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.
|
||||
* TSC (Time Stamp Counter): Internal processor clock incremented at
|
||||
each processor cycle. Its frequency is the processor frequency and
|
||||
so usually higher than 1 GHz. Its priority is 300 by default, but
|
||||
falls to 0 if the processor frequency changes and the counter
|
||||
becomes unstable.
|
||||
* HPET: An 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.
|
||||
* PIT (programmable interrupt timer): Intel 8253/8254 chipsets with a
|
||||
configurable frequency in range 18.2 Hz - 1.2 MHz. Linux uses the
|
||||
frequency 1,193,181.8 Hz. It is a 16-bit counter.
|
||||
* PMTMR (power management timer): ACPI 24-bit timer with a frequency
|
||||
of 3.5 MHz (3,579,545 Hz). Its priority is 200 by default, but
|
||||
changes to 110 if the chipset is broken and need a software
|
||||
workaround. HPET can cause around 3 seconds of drift per day.
|
||||
* 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.
|
||||
|
||||
High-resolution timers are not supported on all hardware architectures. They
|
||||
are at least provided on x86/x86_64, ARM and PowerPC.
|
||||
High-resolution timers are not supported on all hardware
|
||||
architectures. They are at least provided on x86/x86_64, ARM and
|
||||
PowerPC.
|
||||
|
||||
The list of available clock sources can be read in
|
||||
/sys/devices/system/clocksource/clocksource0/available_clocksource. It is
|
||||
possible to force a clocksource at runtime by writing its name into
|
||||
/sys/devices/system/clocksource/clocksource0/current_clocksource.
|
||||
/sys/devices/system/clocksource/clocksource0/available_clocksource.
|
||||
It is possible to force a clocksource at runtime by writing its name
|
||||
into /sys/devices/system/clocksource/clocksource0/current_clocksource.
|
||||
/proc/timer_list contains the list of all hardware timers.
|
||||
|
||||
Read also the `time(7) manual page
|
||||
|
@ -579,14 +608,14 @@ Name of the "monotonic or fallback" function name
|
|||
|
||||
Other names were proposed:
|
||||
|
||||
* time.hires(): "hires" can be read as "to hire" as in "he hires a car to go
|
||||
on holiday", rather than a "HIgh-RESolution clock".
|
||||
* time.steady(): no OS provides a clock advancing at a steady rate, so
|
||||
"steady" should be avoided.
|
||||
* time.try_monotonic(): it is a clear and obvious solution for the use-case of
|
||||
"I prefer the monotonic clock, if it is available, otherwise I'll take my
|
||||
chances with a best-effect clock."
|
||||
* time.wallclock()
|
||||
* time.hires(): "hires" can be read as "to hire" as in "he hires a car
|
||||
to go on holiday", rather than a "HIgh-RESolution clock".
|
||||
* time.steady(): no OS provides a clock advancing at a steady rate, so
|
||||
"steady" should be avoided.
|
||||
* time.try_monotonic(): it is a clear and obvious solution for the
|
||||
use-case of "I prefer the monotonic clock, if it is available,
|
||||
otherwise I'll take my chances with a best-effect clock."
|
||||
* time.wallclock()
|
||||
|
||||
|
||||
One function, no flag
|
||||
|
@ -594,33 +623,36 @@ One function, no flag
|
|||
|
||||
time.monotonic() returns (time: float, is_monotonic: bool).
|
||||
|
||||
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().
|
||||
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().
|
||||
|
||||
|
||||
Working around operating system bugs?
|
||||
=====================================
|
||||
|
||||
Should Python ensure manually that a monotonic clock is truly monotonic by
|
||||
computing the maximum with the clock value and the previous value?
|
||||
Should Python ensure manually that a monotonic clock is truly
|
||||
monotonic by computing the maximum with the clock value and the
|
||||
previous value?
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
* Virtual machines provide less reliable clocks.
|
||||
* QueryPerformanceCounter() has known bugs (only one is not fixed yet)
|
||||
* Virtual machines provide less reliable clocks.
|
||||
* QueryPerformanceCounter() has known bugs (only one is not fixed yet)
|
||||
|
||||
Python may only workaround a specific known operating system bug: `KB274323`_
|
||||
contains a code example to workaround the bug (use GetTickCount() to detect
|
||||
QueryPerformanceCounter() leap).
|
||||
Python may only workaround a specific known operating system bug:
|
||||
`KB274323`_ contains a code example to workaround the bug (use
|
||||
GetTickCount() to detect QueryPerformanceCounter() leap).
|
||||
|
||||
|
||||
Footnotes
|
||||
=========
|
||||
|
||||
.. [#pseudo] "_time" is an hypothetical module only used for the example.
|
||||
The time module is implemented in C and so there is no need for such module.
|
||||
The time module is implemented in C and so there is no need for
|
||||
such module.
|
||||
|
||||
|
||||
Links
|
||||
|
@ -628,61 +660,79 @@ Links
|
|||
|
||||
Related Python issues:
|
||||
|
||||
* `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>`_
|
||||
* `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>`_
|
||||
* `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>`_
|
||||
* `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>`_
|
||||
|
||||
Librairies exposing monotonic clocks:
|
||||
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>`_)
|
||||
* `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.
|
||||
* `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>`_)
|
||||
* `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.
|
||||
|
||||
Time:
|
||||
|
||||
* `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
|
||||
* `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
|
||||
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
This document has been placed in the public domain.
|
||||
|
||||
|
||||
|
||||
..
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
sentence-end-double-space: t
|
||||
fill-column: 70
|
||||
coding: utf-8
|
||||
End:
|
||||
|
|
Loading…
Reference in New Issue