23

OS: Windows 7

When calling the WinAPI Sleep() function as Sleep(1) the thread actually sleeps for 15ms. I did it 100 times in a loop and the total sleep time was 1500ms instead of 100.

Is this common behavior or should I be concerced about something being wrong with my MOBO, CPU, Windows installion?

EDIT: If possible could you run this code and post how long the sleep time was. I let a friend of mine run this, and he actually had it all at 1ms.

#include <iostream>
#include <ctime>
#include <Windows.h>

void test(void)
{
    std::cout << "Testing 1ms sleep." << std::endl;

    for (unsigned int i = 0; i < 10; i++)
    {
        std::clock_t startClocks = std::clock();

        Sleep(1);

        std::clock_t clocksTaken = std::clock() - startClocks;
        std::cout << "Time: " << clocksTaken << "ms." << std::endl;
    }
}

int main(void)
{
    test();

    std::cin.sync();
    std::cin.get();
    return 0;
}

EDIT2: It seems that the reason why some people are getting 1ms is that some other program is running that sets the system-wide timer resolution to 1ms. By default this should be 15.6ms on Windows 7.

NFRCR
  • 5,304
  • 6
  • 32
  • 37
  • Since Sleep can easily take a different time depending on various factors (the hardware/os it's running on, the load of the processor at that time etc.) I'm not sure what you hope to achieve by asking people to run that code. It'd be perfectly possible for it to output a different time for every iteration of the loop, every single time it runs. – obmarg Mar 01 '12 at 16:43
  • 3
    I don't think Sleep() is hardware specific on Windows. If you're not running any programs that use timeBeginPeriod() then the results should be 15-16ms. For example: Windows Media Player sets it to 10ms, and BSPlayer to 1ms. It has also been said that some browsers adjust it. – NFRCR Mar 01 '12 at 17:07
  • 1
    Perhaps it's not directly connected, but there could still be an indirect link - if you're running windows on a vastly underpowered machine the load would go up and the time before Sleep returns could also. – obmarg Mar 01 '12 at 17:14
  • You need to accept answers that work for you, or folks will stop answering your questions. Click on the green checkmark by the answer you like the best. – Ethan Furman Mar 13 '12 at 21:36

8 Answers8

18

Is this common behavior

It is.

Window's thread scheduler works on a time quantum (exact length depends of various factors including Windows version and edition). Effectively any non-zero delay is rounded up to a complete quantum.

Richard
  • 106,783
  • 21
  • 203
  • 265
  • 1
    @MatteoItalia A zero sleep will immediately return if there is nothing else available to run (at this or higher priority): it may not block at all. With a non-zero value, as I understand it, there will always be some blocking. – Richard Mar 01 '12 at 14:45
13

Sleep can cause the thread to sleep for longer than the timeout specified, it only guarantees that the thread will sleep for at least that length of time.

From the documentation:

After the sleep interval has passed, the thread is ready to run. If you specify 0 milliseconds, the thread will relinquish the remainder of its time slice but remain ready. Note that a ready thread is not guaranteed to run immediately. Consequently, the thread may not run until some time after the sleep interval elapses. For more information, see Scheduling Priorities.

Azeem
  • 11,148
  • 4
  • 27
  • 40
obmarg
  • 9,369
  • 36
  • 59
6

The best articles I have found regarding timing on Windows are here and here. The useful part is that once you change the multimedia timer resolution (e.g. timeBeginPeriod(1) for 1ms) it also affects the Sleep command, because it affects the scheduler in general. This said, achieving 1ms accuracy is not feasible on a non-realtime OS.

dashesy
  • 2,596
  • 3
  • 45
  • 61
1

The behavior is OK. Underlying hardware, version of OS, and even running software are influencing the habit of the OS with respect to the sleep() function.

If a sleep is called with dwMilliseconds smaller than the systems interrupt period, the call will return at the next interrupt. This way the actual delay depends on the time at which the sleep was called (with respect to the interrupt period).

It is advisable to use the multimedia timer interface to increase the interrupt frequency to the maximum supported by the hardware, when a sleep(1) is desired.

A detailed overview about the sleep() function, waitable timer functions, timer resolutions, and multimedia timer settings can be found at the Windows Timestamp Project

Arno
  • 4,994
  • 3
  • 39
  • 63
1

You should check your machine's timer resolution. See the msdn documentation of Sleep() for details.

Asaf
  • 4,317
  • 28
  • 48
1

This is pretty normal behavior, as most clock resolutions are around 10-15 ms. Therefore, if you call it with a value less than the clock resolution (in your case, 1), it will likely have to wait at least for one clock cycle, which is why it sleeps longer than you want to.

Generally, you should not use Sleep for things requiring such precision due to these issues.

houbysoft
  • 32,532
  • 24
  • 103
  • 156
0

Expected. Recently I was also debugging an issue related to this. If I call sleep with 1 millisecond, It will sleep for 15 milliseconds. It makes sense to assume that the actual sleep time will always be rounded up to a multiple of 15ms.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 10 '22 at 14:12
0

(debug or release build ?)

How are you measuring the delay ? are you using a precise method ? (queryperformancecounter)

I don't think you should rely on the Windows OS for accurate timing; it is not a real-time operating system, and there will be external "forces" that will steal time from your process.

Max
  • 3,128
  • 1
  • 24
  • 24