"Pavel A." <pa*****@NOwritemeNO.comwrote in message
news:OP**************@TK2MSFTNGP03.phx.gbl...
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
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*)&startcoun t);
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.