I have two questions numbered below.
My understanding is that on a Windows OS, Python3's time.perf_counter() will usually (unless there is some underlying hardware problem that prevents this), return a timestamp, roughly corresponding to QueryPerformanceCounter() / QueryPerformanceFrequency().
(1) What I do not know, is whether Python locks each call to the same core or thread using SetThreadAffinityMask or something similar (here, I thinking of the kinds of problem encountered in this question asked in 2017 (QueryPerformanceCounter on multi-core processor under Windows 10 behaves erratically).
I know that PsychToolbox's GetSecs goes through a fairly elaborate procedure to do so. I've taken a look at Python's pytime.c, and I don't see anything like that, but I'm hoping that someone more familiar with the code than I am might have an answer.
(2) In the question in linked to above, one of the answers links to a MSDN article describing the problem in depth. However, the current MSDN documentation, updated in 2018, appears much more optimistic about the situation:
In general, the performance counter results are consistent across all processors in multi-core and multi-processor systems, even when measured on different threads or processes. Here are some exceptions to this rule:
Pre-Windows Vista operating systems that run on certain processors might violate this consistency because of one of these reasons:
- The hardware processors have a non-invariant TSC and the BIOS doesn't indicate this condition correctly.
- The TSC synchronization algorithm that was used wasn't suitable for systems with large numbers of processors.
When you compare performance counter results that are acquired from different threads, consider values that differ by ± 1 tick to have an ambiguous ordering. If the time stamps are taken from the same thread, this ± 1 tick uncertainty doesn't apply. In this context, the term tick refers to a period of time equal to 1 ÷ (the frequency of the performance counter obtained from QueryPerformanceFrequency).
So, based on your real-life experience, is that actually the case? Is locking the timer to a particular core so important these days?