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:
Georg Brandl 2012-03-31 08:38:41 +02:00
parent 72a7239f0e
commit 2534727122
1 changed files with 330 additions and 280 deletions

View File

@ -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: