Click here to Skip to main content
15,888,610 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I try to measure the 'exact' sleep time when I use Sleep() in C++.

So, I used this code

C++
#include <stdio.h>
#include <intrin.h>
#include <windows.h>
#include <iostream>
using namespace std;

unsigned __int64 testSleepExactTime(int relax);
unsigned __int64 getFreqFrom__rdtsc();

int main()
{
	unsigned int relax = 0;
	unsigned __int64 freq = 0;
	freq = getFreqFrom__rdtsc();
	cout <<"Input Relax time (millisec): ";
	cin >> relax;
	cout <<"relax Time : " << relax * 1000<<" Micro Sec."<<endl;
	cout <<"System frequency : "<<freq<<" Ticks per sec."<<endl;
	for(int i = 0;i<10;i++)
		cout <<"Exact relax time : " << testSleepExactTime(relax)*1000000/freq <<" Micro Sec."<< endl;
	for(int i = 0;i<10;i++)
		cout <<"Exact relax time(Double) : " << ((double)testSleepExactTime(relax))*1000000/freq <<" Micro Sec."<< endl;

	system("pause");
	return 0;
}
unsigned __int64 testSleepExactTime(int relax)
{
	unsigned __int64 start = 0;
	unsigned __int64 stop = 0;
	start = __rdtsc();
	Sleep(relax);
	stop = __rdtsc();
	return stop - start;
}
unsigned __int64 getFreqFrom__rdtsc()
{
	 unsigned __int64 start = 0;
	 unsigned __int64 stop = 0;
	 start = __rdtsc();
     Sleep(1000);
	 stop = __rdtsc();
	return stop-start;
}


when I input 1 millisecond, it resuted 10000 Microsecond
when I input 1000 millisecond, it resuted 995000 Microsecond

why when I use 1 millisecond that result seem incorrect?

note:
Using MSVC++2010 as tool
Base on Windows7
CPU i3 3.07GHz
PS. I'm not using 'QueryPerformanceFrequency()' because it returns ~2.9m ticks per sec.
Posted
Updated 20-Dec-11 2:52am
v2
Comments
Albert Holguin 20-Dec-11 10:18am    
By the way, in Windows, there's no accurate reading to the microsecond level, so your results are not really valid anyway.

Generally, when you try to sleep for 1 millisecond, the cpu sleeps for about 20-25 milliseconds due to the resolution of the clock on the CPU. If you google "cpu clock resolution" you'll probably find more in-depth descriptions of what's going on.
 
Share this answer
 
Comments
windyl3ig 20-Dec-11 9:58am    
ok, That's time resolution problem. thanks you very much >w<
Albert Holguin 20-Dec-11 11:25am    
Yep, typically, when there's an operating system involved, you're not going to be able to have a great amount of resolution due to the amount of overhead going on and the time-division multiplexing of instructions used by the OS to divide processor time amongst all processes.
Sleep() takes an argument specifying the number of milliseconds before returning. Let's call that argument "x"

Sleep() (or any other form of timeout) in Windows does not guarantee that you will resume in exactly 'x' milliseconds. It does not even guarantee that you will resume in anywhere near 'x' milliseconds. Here's why.

Your process (thread) is just one of a number of processes / threads running in your PC. Open Task Manager and look at the processes tab. Click the View menu and add the "Threads" and "Base Priority" items. Now look at the list.

Your process is competing for compute resources with every thread inside every process running in your PC. Look at the Base Priority column and you'll see that there are many processes listed as having a higher priority than yours. These will all prempt you if they need the cpu. There are a number of processes listed as having the same priority as yours. You will take turns with these processes.

So, when your Sleep() is finished, your process (thread) is once again allowed to compete with these other processes for the cpu's attention. You are not guaranteed to get it first.

To summarize:

1) as others have pointed out to you, the clock resolution is not exactly at 1 millisecond granularity so your Sleep() will not complete in exactly 'x' milliseconds, but rather will complete sometime after 'x' milliseconds have elapsed.

2) once the time has elapsed and your process (thread) is eligible to run again, it has to compete with everything else that is happening inside your PC at that moment and may have to wait its turn to resume execution.

And to your other issue in your question:

Your algorithm for figuring out freq is flawed because it relies on Sleep(1000) to calibrate the value and, as I've demonstrated, Sleep() cannot be used for this purpose and is inherently imprecise.
 
Share this answer
 
Comments
windyl3ig 20-Dec-11 12:01pm    
Thank you for your comment, and more in-depth detail about Sleep().
but my question is how to figure out CPU freq, as I demonstrate that QureyPreformanceFrequence() is not really work, my CPU clock is 3.07 GHz but that function return only "~2.9MHz".
Chuck O'Toole 20-Dec-11 12:47pm    
Actually, your question was "why when I use 1 millisecond that result seem incorrect?" and that's what I answered. If you want to know about QueryPerformanceFrequency(), that's a whole other question.
Re: QueryPeroformanceFrequency():

Read Microsoft's description and the "community comments" on it.

QueryPerformanceFrequency()[^]

As one person noted, you are querying the frequency of the timer, not the frequency of the cpu processor. So regardless of what your CPU Chip speed is, this is a different "frequency".

Consider if the performance counter was, in fact, the cpu cycle speed. Then would the number change when you switched to battery power? Certainly your processor chip speed does. How about "turbo boost" mode? If the cpu cycle speed were variable as it is in modern chips and under certain circumstances, the high percision timer would be useless.

Microsoft's documentation clearly states :
Quote:
The frequency cannot change while the system is running.
which implies that it does not follow the ups and downs of the cpu chip clock speed.
 
Share this answer
 
If your question is "How do I find out the CPU Chip Speed", which seems to be what you are asking in one of your replies, Microsoft has an article which describes the various ways to find it in the registry or other places.

http://support.microsoft.com/kb/888282[^]

Again with the proviso that the cpu chip cycle speed can vary during the course of the day. Given that, the information is "interesting" but hardly "useful".
 
Share this answer
 
Comments
windyl3ig 20-Dec-11 13:49pm    
oh that's awesome. Very thank you for your comment and guidlines.
It's very useful for me. And again, Thank you very much.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900