I originally asked about this on coderanch.com, so if you tried to help me there, thank you and don't feel obligated to repeat the effort. coderanch.com is basically the Java community, and it seems (after some research) really a Windows issue, so my colleagues are there, and I thought it might be a better place to look for help.
I wrote a short program that either spins on the Windows performance counter until 33 ms has passed, or calls "Sleep" (33). The former does not show any unexpected effects, but the latter apparently (steadily) slows down subsequent processing for about 40 ms (either this or has some effect on the values โโreturned from the performance counter for this long). After rotation or sleep (), the program calls the runInPlace () procedure, which rotates for 2 ms, counting the number of requests to the performance counter and returning this number.
When the initial 33 ms delay is performed by rotation, the number of iterations of runInPlace (), as a rule (on my Windows 10, XPS-8700), is about 250,000. It changes, probably due to other system overheads, but it changes the smoothing about 250,000.
Now that the initial delay is done by calling Sleep (), something strange is happening. Many calls to runInPlace () return a number around 250,000, but many of them return a number around 50,000. Again, the range is around 50,000, pretty smoothly. But, obviously, he averages one or another, almost anywhere from 80,000 to 150,000 people return. If I call runInPlace () 100 times after each delay, and not just once, it will never return the number of iterations in a smaller range after the 20th call. Since runInPlace () runs for 2 ms, this means that the behavior that I am observing disappears after 40 ms. If I run runInPlace () in 4 ms instead of 2 ms, it never returns the number of iterations in a smaller range after the 10th call, so again the behavior disappears after 40 ms (similarly, if runInPlace () only works for 1 ms; behavior disappears after the 40th call).
Here is my code:
#include "stdafx.h" #include "Windows.h" int runInPlace(int msDelay) { LARGE_INTEGER t0, t1; int n = 0; QueryPerformanceCounter(&t0); do { QueryPerformanceCounter(&t1); n++; } while (t1.QuadPart - t0.QuadPart < msDelay); return n; } int _tmain(int argc, _TCHAR* argv[]) { LARGE_INTEGER t0, t1; LARGE_INTEGER frequency; int n; QueryPerformanceFrequency(&frequency); int msDelay = 2 * frequency.QuadPart / 1000; int spinDelay = 33 * frequency.QuadPart / 1000; for (int i = 0; i < 100; i++) { if (argc > 1) Sleep(33); else { QueryPerformanceCounter(&t0); do { QueryPerformanceCounter(&t1); } while (t1.QuadPart - t0.QuadPart < spinDelay); } n = runInPlace(msDelay); printf("%d \n", n); } getchar(); return 0; }
Here's some output typical of what I get when using Sleep () for a delay:
56116 248936 53659 34311 233488 54921 47904 45765 31454 55633 55870 55607 32363 219810 211400 216358 274039 244635 152282 151779 43057 37442 251658 53813 56237 259858 252275 251099
And here are some of the results specific to what I get when I spin to create a delay:
276461 280869 276215 280850 188066 280666 281139 280904 277886 279250 244671 240599 279697 280844 159246 271938 263632 260892 238902 255570 265652 274005 273604 150640 279153 281146 280845 248277
Can someone help me understand this behavior? (Note that I tried this program compiled with Visual C ++ 2010 Express on five computers. This only shows this behavior on the two fastest machines I have.)