Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / April 2008

Tip: Looking for answers? Try searching our database.

High resolution Sleep

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Charles Zhang - 02 Apr 2008 05:09 GMT
Sleep() function Sleep at lease 1 millisecond, there is a way to make a
thread to sleep less than a millisecond? One way I know of is using
performance counter which is not really sleep ( loop and check again and
again and uses CPU time).

Thanks

Charles Zhang
Mark Salsbery [MVP] - 02 Apr 2008 06:28 GMT
Even Sleep() doesn't have true 1 ms resolution.

There's no better timer than the performance counter in Windows AFAIK.

Mark

Signature

Mark Salsbery
Microsoft MVP - Visual C++

> Sleep() function Sleep at lease 1 millisecond, there is a way to make a
> thread to sleep less than a millisecond? One way I know of is using
[quoted text clipped - 4 lines]
>
> Charles Zhang
Jordi Maycas - 02 Apr 2008 11:10 GMT
and.. what about with time struct?

hh:mm:ss,dd

where 99>=dd>=0

dd are miliseconds...

and thinking a little more, what about cpu cicles?

> Even Sleep() doesn't have true 1 ms resolution.
>
[quoted text clipped - 10 lines]
>>
>> Charles Zhang
Mark Salsbery [MVP] - 02 Apr 2008 17:46 GMT
> and.. what about with time struct?
>
[quoted text clipped - 3 lines]
>
> dd are miliseconds...

Yes, many APIs have 1ms units in parameters.  Some use 100-nanosecond units.
But the actual accuracy is much less than 1ms.

See Charles Wang's response below...

> and thinking a little more, what about cpu cicles?

Now you're at the performance counter level :)

Mark

Signature

Mark Salsbery
Microsoft MVP - Visual C++

>> Even Sleep() doesn't have true 1 ms resolution.
>>
[quoted text clipped - 10 lines]
>>>
>>> Charles Zhang
RFOG - 02 Apr 2008 11:22 GMT
You can use "clockres" from Sysinternals (today Microsoft) to see the
minimum resolution in your machine. Mine (Quad core is 15.6 ms).

I think less than 15 ms is impossible, and surely a sleep of 15 ms becomes
in a lot of more time because Windows uses that sleeping to do other tasks,
and if you put a for() loop you will get your CPU time scalated to 100% and
surely with no more precission that sleep.

> Sleep() function Sleep at lease 1 millisecond, there is a way to make a
> thread to sleep less than a millisecond? One way I know of is using
[quoted text clipped - 4 lines]
>
> Charles Zhang

Signature

Microsoft Visual C++ MVP
========================
Mi blog sobre programación: http://geeks.ms/blogs/rfog
Momentos Leves: http://momentosleves.blogspot.com/
Libros, ciencia ficción y  programación
========================================
Es un hecho que el hombre tiene que controlar la ciencia y chequear
ocasionalmente el avance de la tecnología.
 -- Thomas Henry Huxley.

Jochen Kalmbach [MVP] - 02 Apr 2008 12:09 GMT
Hi RFOG!

> I think less than 15 ms is impossible, and surely a sleep of 15 ms
> becomes in a lot of more time because Windows uses that sleeping to do
> other tasks, and if you put a for() loop you will get your CPU time
> scalated to 100% and surely with no more precission that sleep.

If you use "timeBeginPeriod(1)" you can mostly reduce the time-slice to
2 ms.

Greetings
  Jochen
Willy Denoyette [MVP] - 02 Apr 2008 12:37 GMT
> Hi RFOG!
>
[quoted text clipped - 8 lines]
> Greetings
>   Jochen

True, but this won't guarantee that your thread will get scheduled right
after 2ms. The scheduler is master of the game here, once you give up your
quantum, you'll have to wait until all other higher priority threads have
run.

Willy.
Jochen Kalmbach [MVP] - 02 Apr 2008 12:42 GMT
Hi Willy!

> True, but this won't guarantee that your thread will get scheduled right
> after 2ms. The scheduler is master of the game here,

Yes...

> once you give up
> your quantum, you'll have to wait until all other higher priority
> threads have run.

No. If a higher prio thread becomes ready to run, your quantum does not
matter. Your thread will be immediately interrupted and the higher prio
thread will run.

Greetings
  Jochen
Jochen Kalmbach [MVP] - 02 Apr 2008 12:48 GMT
Hi Willy!

> No.

I wanted to say: This is only some side of the truth... sorry...

Greetings
  Jochen
Willy Denoyette [MVP] - 02 Apr 2008 13:06 GMT
> Hi Willy!
>
[quoted text clipped - 9 lines]
> matter. Your thread will be immediately interrupted and the higher prio
> thread will run.

Hi Jochen,

I mean :
T1 normal priority calls sleep(2) - that is, give up your quantum now!
T2 normal priority gets scheduled runs for 1msec and enters a wait state
T3 higher priority  gets scheduled and runs for 1 sec.
T1 as slept ~1 sec
Sure above assumes a single proc machine :-)

Grüßen,
Willy.
Ben Voigt [C++ MVP] - 02 Apr 2008 16:40 GMT
>> Hi Willy!
>>
[quoted text clipped - 17 lines]
> state T3 higher priority  gets scheduled and runs for 1 sec.
> T1 as slept ~1 sec

This isn't a drawback to calling sleep though, any wait method could be
pre-empted by a higher priority thread.

> Sure above assumes a single proc machine :-)
>
> Grüßen,
> Willy.
Willy Denoyette [MVP] - 02 Apr 2008 17:02 GMT
>>> Hi Willy!
>>>
[quoted text clipped - 25 lines]
>> Grüßen,
>> Willy.
Willy Denoyette [MVP] - 02 Apr 2008 17:30 GMT
>>> Hi Willy!
>>>
[quoted text clipped - 20 lines]
> This isn't a drawback to calling sleep though, any wait method could be
> pre-empted by a higher priority thread.

True, and for the same reason you can't use them to "wait" for an "exact"
(especially small)  amount of time when running on a Windows OS (even not on
Windows CE). Point is that once your (1) thread enters a wait state, you are
at the "mercy" of the scheduler to (2) wake you up. You are under control of
the first action, but you aren't of the second.
So whether you call Sleep(1) or WaitForSingleObject(..., 1), you will wait
for at *least* the RTC timer interval, whatever it's value.

Willy.
Ben Voigt [C++ MVP] - 02 Apr 2008 18:52 GMT
>>>> Hi Willy!
>>>>
[quoted text clipped - 27 lines]
> wake you up. You are under control of the first action, but you
> aren't of the second.

In any OS with virtual memory, you aren't in complete control of #1 (you can
enter a wait state due to page fault).
And with preemptive multitasking, being non-runnable due to a wait state
isn't the only reason for a context switch.

> So whether you call Sleep(1) or WaitForSingleObject(..., 1), you will
> wait for at *least* the RTC timer interval, whatever it's value.

True, although this is an OS design issue.  See for example the new tickless
support in the linux kernel, where the RTC is programmed based on the waits
requested by applications as well as the scheduler quantum instead of
running with a fixed interval, this gives all the benefits of a
high-frequency RTC interrupt with none of the overhead of extra processing
(although it is a little more complicated).

> Willy.
Willy Denoyette [MVP] - 02 Apr 2008 19:38 GMT
>>>>> Hi Willy!
>>>>>
[quoted text clipped - 37 lines]
>
> True, although this is an OS design issue.
Yep, but  we are discussing Windows OS services here right?
On Windows, whenever you try to lower the RTC clock interval (say something
like 1 or 2 msec.), then the system starts to behave eratically (NT4 even
fails to boot), dont know about Vista and later, but clearly Windows is not
built to deal with such short RTC intervals. Note that here I mean
programming the RTC at the BIOS level, not by calling timeBeginPeriod.

See for example the new tickless
> support in the linux kernel, where the RTC is programmed based on the
> waits requested by applications as well as the scheduler quantum instead
> of running with a fixed interval, this gives all the benefits of a
> high-frequency RTC interrupt with none of the overhead of extra processing
> (although it is a little more complicated).

The same is more or less possible with Windows CE, which gives a user
program some more control over the scheduler, which runs at a 1 msec timer
interval by default (also the minimum).

Willy.
Pavel A. - 02 Apr 2008 23:04 GMT
You can get Sleep() delay on XP close to the current timer resolution
but measuring the actual sleep time can be difficult.
I've made a simple test based on Sysinternals clockres sample.

The minimal resolution is  1 or  2 ms on most modern systems where the
default is 15.6 ms, and 1 ms on older systems where the default was 10 ms.
AFAIK there still is no good explanation why the newer PCs have default
resolution > 10 ms.

Surprising is that value returned by GetSystemTimeAsFileTime or
NtQuerySystemTime
seems to update only once in system clock tick (15.6 ms in my case),
so when I call GetSystemTimeAsFileTime  before and after Sleep(1), I got
_same_ value 7 times out of 8;
and on 8th time the difference jumps to 15 ms :(   So the average Sleep()
delay of many samples is close to 1 ms.

Regards,
--PA
Ben Voigt [C++ MVP] - 02 Apr 2008 23:11 GMT
> You can get Sleep() delay on XP close to the current timer resolution
> but measuring the actual sleep time can be difficult.

Not difficult, just use QueryPerformanceCounter.

> I've made a simple test based on Sysinternals clockres sample.
>
[quoted text clipped - 13 lines]
> Regards,
> --PA
Willy Denoyette [MVP] - 03 Apr 2008 00:19 GMT
> You can get Sleep() delay on XP close to the current timer resolution
> but measuring the actual sleep time can be difficult.
[quoted text clipped - 15 lines]
> Regards,
> --PA

Indeed, measuring is the key, but as I said before, you can't Sleep (or
Wait) for a reliable amount of time,
when sleeping (waiting)  for < RTC interval, you give up your remaining
quantum, and you may possibly get re-scheduled after this period of time,
that is, after X msec. where X >= the remaining quantum.
For instance when you call Sleep(1) after your thread has run for Y msec,
you will probably sleep for 15.6 - X msec. on current multi-core/SMP
systems.
When you call Sleep(1) after your thread consumed 10 µsec of it's quantum,
this thread will sleep for at least 15.6 msec.
When you call Sleep(1) after your thread has consumed 14 msec you will sleep
for at least 1.6 msec.
That means you cannot reliably sleep with Windows ;-)

Compile and run the following sample , you'll see what I mean.

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <process.h>
#include <cstdio>
#include <math.h>
unsigned __stdcall Run(void* dummy)
{
double r = 0.0;
for(int i = 0; i < 50000000; i++)
{
 r += (double)sqrt((double)i);
}
printf_s("%Lf\n", r);
_endthreadex(0);
return 0;
}
int main() {
__int64 startcount, stopCount, frequ;
QueryPerformanceFrequency((LARGE_INTEGER*)&frequ);
HANDLE tHandle;
unsigned thread_Id;
Sleep(1); // Give up the current quantum so we can start with a fresh one
after return
tHandle = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, &Run, 0, 0,
&thread_Id ));
QueryPerformanceCounter((LARGE_INTEGER*)&startcount);
Sleep(1);
//Or, use next
// WaitForSingleObject(tHandle, 1); // wait for thread to finish or timeout
QueryPerformanceCounter((LARGE_INTEGER*)&stopCount);
CloseHandle(tHandle);
printf_s("%Lf seconds\n", (double)(stopCount - startcount)/frequ);
return 0;
}

Willy.
Pavel A. - 03 Apr 2008 02:32 GMT
thanks, point taken.
What are typical quantum values for the default priority class on  XP and
CE?

--PA

>> You can get Sleep() delay on XP close to the current timer resolution
>> but measuring the actual sleep time can be difficult.
[quoted text clipped - 72 lines]
>
> Willy.
Ben Voigt [C++ MVP] - 03 Apr 2008 15:00 GMT
> thanks, point taken.
> What are typical quantum values for the default priority class on  XP
> and CE?

on desktop windows, at least, it depends on what other programs are running.
See the documentation for timeBeginPeriod.

> --PA
>
[quoted text clipped - 75 lines]
>>
>> Willy.
Willy Denoyette [MVP] - 03 Apr 2008 16:50 GMT
The thread quanta on XP depend on whether a thread belongs to a foreground
or a background process, foreground threads have a quantum of 6 (RTC ticks),
others have a quantum of 2. Note that these are the default values and
assume that the priorities are the same, the real quantum can vary at run
time, the scheduler can boost the quantum with a value stored in the
registry.
Don't know the details for CE.
Willy.

> thanks, point taken.
> What are typical quantum values for the default priority class on  XP and
[quoted text clipped - 78 lines]
>>
>> Willy.
Charles Wang[MSFT] - 02 Apr 2008 12:52 GMT
Hi Charles,
Actually 1 millisecond is also not possible for Sleep function. Though you
can specify 1, the real value may be 10 or more. To get high resolution
timers that below 10 milliseconds, you need to call the kernel-mode
function NtSetTimerResolution, however for your higher timer resolution
requirement (within 1 millisecond), I am afraid that it is not possible at
upper language level. Maybe you can implement it via assemble language by
controlling interruption.

For more information, you may refer to the following article:
Inside Windows NT High Resolution Timers
http://technet.microsoft.com/en-us/sysinternals/bb897569.aspx

Hope this give you some hints for your reviewing your requirements and
design.

Best regards,
Charles Wang
Microsoft Online Community Support
===========================================================
Delighting our customers is our #1 priority. We welcome your
comments and suggestions about how we can improve the
support we provide to you. Please feel free to let my manager
know what you think of the level of service provided. You can
send feedback directly to my manager at: msdnmg@microsoft.com.
===========================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for
non-urgent issues where an initial response from the community
or a Microsoft Support Engineer within 1 business day is acceptable.
Please note that each follow up response may take approximately
2 business days as the support professional working with you may
need further investigation to reach the most efficient resolution.
The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by
contacting Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
============================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
=========================================================
Ben Voigt [C++ MVP] - 02 Apr 2008 16:42 GMT
> Sleep() function Sleep at lease 1 millisecond, there is a way to make
> a thread to sleep less than a millisecond? One way I know of is using
> performance counter which is not really sleep ( loop and check again
> and again and uses CPU time).

Waitable Timers allow the wait to be specified very precisely, however the
actual resolution will depend on the system clock interrupt.
timeBeginPeriod can make the clock interrupt faster to a point, I don't know
of any user-mode way to set the interrupt rate above 1kHz.

> Thanks
>
> Charles Zhang

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.