C++11 chrono::sleep_for or sleep_unit did not work for microsecond resolution

Swanand 101 Reputation points
2022-04-28T12:25:50.907+00:00

My goal is to create callable microsecond timer event. Based on user time requirement it will provide callback event. Resolution for timer is microseconds min 100 to max 500 micro sec.
I was using C++ chrono interface and observe that it did not wait accurately for that time period.
Here is my sample code

main()
{
int nTimerValue = 100; //wait for 100 ms
for (int i = 0; i < 50; ++i)
{
auto start = std::chrono::steady_clock::now();
std::this_thread::sleep_for(std::chrono::microseconds(nTimerValue));
auto clock_end = std::chrono::steady_clock::now();
long lElapsetimeMs = std::chrono::duration_cast<std::chrono::microseconds>(clock_end - start).count();
char szBuff[255];
sprintf_s(szBuff, "[%d] slept Time: %d MiroSec\n", i, lElapsetimeMs);
cout << szBuff;
::OutputDebugString(szBuff);
}
}

which results in output:
[0] slept Time: 1869 MiroSec
1 slept Time: 1761 MiroSec
[2] slept Time: 1723 MiroSec
[3] slept Time: 1869 MiroSec
[4] slept Time: 1764 MiroSec
[5] slept Time: 1859 MiroSec
[6] slept Time: 1802 MiroSec
[7] slept Time: 1729 MiroSec
[8] slept Time: 1824 MiroSec
[9] slept Time: 1731 MiroSec
...

I did try with std::this_thread::sleep_until API also but it didn't help.
Also I observe, there are same finding for Win7 https://developercommunity.visualstudio.com/t/stdthis-threadsleep-for-and-company-can-sleep-for/218129?viewtype=all

Another work around is to use while loop pooling for time out event, which result in CPU usage but looks more promising that using thread timer.
while (std::chrono::system_clock::now() < start + std::chrono::microseconds(<timer_value>)) {}

Is there any known limitation of using this API? Is it possible to design microsecond timer using (min 100 microsec) on Windows environment?
Any other suggestion?

Let me know incase of any query.
Following are my machine config197355-image.png

Developer technologies | C++
{count} votes

Accepted answer
  1. Minxin Yu 13,506 Reputation points Microsoft External Staff
    2022-04-29T02:27:08.553+00:00

    Hi, @BelsareSwanand-1160

    Should be possible on other operating systems.
    Under Windows, even without sleeping you can't ensure that two consecutive instructions will be carried out with less than a millisecond between them.
    Repeatedly checking a suitably high-resolution timer is one approach (for example: QueryPerformanceCounter function), but it burns CPU.

    Best regards,

    Minxin Yu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.