0

I have a simple code running on my 64 bit machine, Windows 7 as a standard windows application :

    do {
        DWORD getCurrentTick = GetTickCount();;
        Sleep(20);
        DWORD nextTick = GetTickCount();

        printf("Tick = %d\n", nextTick - getCurrentTick);
    } while(TRUE);

I know that a user mode thread sleep is not guaranteed to wake on the requested time but the weird thing is that windows wakes before time comes. look at my output :

Tick = 15
Tick = 16
Tick = 16
Tick = 31
Tick = 15
Tick = 16
Tick = 15
Tick = 16
Tick = 31

My question is how come it wakes before my requested time ? and what can I do to make it more precise ?

Nuno_147
  • 2,817
  • 5
  • 23
  • 36
  • You are going far too granular in time there. It's not that accurate. Try significantly longer times and this won't seem like an issue at all. – Andrew Barber Aug 10 '14 at 05:34
  • There are many different varieties of both "sleep" and "get time" APIs in Windows. They don't always synchronize to the same clock. Perhaps if you opened up about what you are really trying to do that requires such precise timing we can advise you better. – selbie Aug 10 '14 at 05:48
  • I don't mind how accurate it is, I was just surprised to see differences that are lower then my requested interval. – Nuno_147 Aug 10 '14 at 06:18
  • You should read the document [Windows Timer Coalescing](http://download.microsoft.com/download/9/C/5/9C5B2167-8017-4BAE-9FDE-D599BAC8184A/TimerCoal.docx) ([Web View](http://view.officeapps.live.com/op/view.aspx?src=http%3A%2F%2Fdownload.microsoft.com%2Fdownload%2F9%2FC%2F5%2F9C5B2167-8017-4BAE-9FDE-D599BAC8184A%2FTimerCoal.docx)). It explains your observations. – IInspectable Aug 10 '14 at 15:32

1 Answers1

4

The OS has a particular quantum for thread scheduling which impacts the accuracy of thread waits. It defaults to 15 ms, so a Sleep of 20 is going to end up either before it or after it. This is "by design".

It is possible in a Win32 desktop app to improve the accuracy by using the old WinMM function timeBeginPeriod(1); but this (a) is a global setting, and (b) greatly reduces the efficiency of the power management.

You should use waitable timer events and not Sleep, but you will still be subject to the thread scheduling quantum for accuracy when the thread is halted.

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81