STINNER Victor <vstin...@python.org> added the comment:
Changing is clock is a tricky. There are many things to consider: * Is it really monotonic in all cases? * Does it have a better resolution than the previous clock? * Corner cases: does it include time spent in time.sleep() and while the system is suspended? * etc. -- When I designed PEP 418 (in 2012), QueryPerformanceCounter() was not reliable: "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." https://www.python.org/dev/peps/pep-0418/#windows-queryperformancecounter And there were a few bugs like: "The performance counter value may unexpectedly leap forward because of a hardware bug". A Microsoft blog article explains that users wanting a steady clock with precision higher than GetTickCount() should interpolate GetTickCount() using QueryPerformanceCounter(). If I recall correctly, this is what Firefox did for instance. Eryk: "That said, Windows 10 also provides QueryInterruptTimePrecise(), which is a hybrid solution. It uses the performance counter to interpolate a timestamp between interrupts. I'd prefer to use this for time.monotonic() instead of QPC, if it's available via GetProcAddress()." Oh, good that they provided an implementation for that :-) -- > V8 uses QueryPerformanceCounter after checking for old CPUs: > https://github.com/v8/v8/blob/dc712da548c7fb433caed56af9a021d964952728/src/base/platform/time.cc#L672 It uses CPUID to check for "non stoppable time stamp counter": https://github.com/v8/v8/blob/master/src/base/cpu.cc // Check if CPU has non stoppable time stamp counter. const unsigned parameter_containing_non_stop_time_stamp_counter = 0x80000007; if (num_ext_ids >= parameter_containing_non_stop_time_stamp_counter) { __cpuid(cpu_info, parameter_containing_non_stop_time_stamp_counter); has_non_stop_time_stamp_counter_ = (cpu_info[3] & (1 << 8)) != 0; } Maybe we use such check in Python: use GetTickCount() on old CPUs, or QueryPerformanceCounter() otherwise. MSVC provides the __cpuid() function: https://docs.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-160 -- > Swift originally used QueryPerformanceCounter, but switched to > QueryUnbiasedInterruptTime() because they didn't want to count time the > system spent asleep Oh, I recall that it was a tricky question. The PEP 418 simply says: "The behaviour of clocks after a system suspend is not defined in the documentation of new functions." See "Include Sleep" and "Include Suspend" columns of my table: https://www.python.org/dev/peps/pep-0418/#monotonic-clocks ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue44328> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com