The following PCs give accurate results:
Gateway E3110-300 Pentium II 300 MHz AL440LX chip set
Gateway GP7-550 Pentium III 500 MHz Intel 440BX chip set
Result from the above PCs:
Sleep(10) executes 100 times in 1000 milliseconds; error = 0 milliseconds
Sleep(20) executes 100 times in 2000 milliseconds; error = 0 milliseconds
Sleep(30) executes 100 times in 3000 milliseconds; error = 0 milliseconds
Sleep(40) executes 100 times in 4000 milliseconds; error = 0 milliseconds
Sleep(50) executes 100 times in 5000 milliseconds; error = 0 milliseconds
Sleep(60) executes 100 times in 6000 milliseconds; error = 0 milliseconds
Sleep(70) executes 100 times in 7000 milliseconds; error = 0 milliseconds
Sleep(80) executes 100 times in 8000 milliseconds; error = 0 milliseconds
Sleep(90) executes 100 times in 9000 milliseconds; error = 0 milliseconds
Sleep(100) executes 100 times in 10000 milliseconds; error = 0 milliseconds
Sleep(110) executes 100 times in 11000 milliseconds; error = 0 milliseconds
Sleep(120) executes 100 times in 12000 milliseconds; error = 0 milliseconds
Sleep(130) executes 100 times in 13000 milliseconds; error = 0 milliseconds
Sleep(140) executes 100 times in 14000 milliseconds; error = 0 milliseconds
Sleep(150) executes 100 times in 15000 milliseconds; error = 0 milliseconds
Sleep(160) executes 100 times in 16000 milliseconds; error = 0 milliseconds
Sleep(170) executes 100 times in 17000 milliseconds; error = 0 milliseconds
Sleep(180) executes 100 times in 18000 milliseconds; error = 0 milliseconds
Sleep(190) executes 100 times in 19000 milliseconds; error = 0 milliseconds
Sleep(200) executes 100 times in 20000 milliseconds; error = 0 milliseconds
The following PCs give inaccurate results:
Compaq Deskpro EN P1.0 GHz Intel 815e chipset
HP Compaq d220 Celeron 2.0 GHz Intel 845GV chipset
Dell Dimension 2400 - Celeron Processor Intel 845GV chipset
HP d530 P4 2.4 GHz Intel 865G chipset
Result from the above PCs:
Sleep(10) executes 64 times in 1000 milliseconds; error = 360 milliseconds
Sleep(20) executes 64 times in 2000 milliseconds; error = 720 milliseconds
Sleep(30) executes 96 times in 3000 milliseconds; error = 120 milliseconds
Sleep(40) executes 86 times in 4000 milliseconds; error = 560 milliseconds
Sleep(50) executes 80 times in 5000 milliseconds; error = 1000 milliseconds
Sleep(60) executes 96 times in 6000 milliseconds; error = 240 milliseconds
Sleep(70) executes 90 times in 7000 milliseconds; error = 700 milliseconds
Sleep(80) executes 86 times in 8000 milliseconds; error = 1120 milliseconds
Sleep(90) executes 96 times in 9000 milliseconds; error = 360 milliseconds
Sleep(100) executes 92 times in 10000 milliseconds; error = 800 milliseconds
Sleep(110) executes 88 times in 11000 milliseconds; error = 1320 milliseconds
Sleep(120) executes 96 times in 12000 milliseconds; error = 480 milliseconds
Sleep(130) executes 93 times in 13000 milliseconds; error = 910 milliseconds
Sleep(140) executes 100 times in 14000 milliseconds; error = 0 milliseconds
Sleep(150) executes 96 times in 15000 milliseconds; error = 600 milliseconds
Sleep(160) executes 94 times in 16000 milliseconds; error = 960 milliseconds
Sleep(170) executes 99 times in 17000 milliseconds; error = 170 milliseconds
Sleep(180) executes 96 times in 18000 milliseconds; error = 720 milliseconds
Sleep(190) executes 94 times in 19000 milliseconds; error = 1140 milliseconds
Sleep(200) executes 99 times in 20000 milliseconds; error = 200 milliseconds
The inaccuracy seems to be related to the chipset. PCs with the 440 chipset
give accurate results. PCs with the 8xx chipset give inaccurate results.
The problem exists on Windows 2000 and Windows XP. The problem exists with
Visual C++ 6.0 and Visual C++.net 2003. Uncommenting the calls to the real
time clock (_ftime) verifies that the Sleep() time is inaccurate.
I use Sleep() to delay between readings from a device. I take readings for
several seconds. The inaccuracy of Sleep() means that I get a significantly
different number of readings from a device when I use a different PC.
Has anyone seen this problem and found a solution?
Example code:
#include <Windows.h>
#include <stdio.h>
#include <conio.h>
#include <sys/timeb.h>
#include <time.h>
void main(void)
{
int i,
iDelay,
iDelayx100;
char *timeline;
clock_t tyStartTick;
struct _timeb timebuffer;
for(iDelay=10; iDelay<=200; iDelay+=10)
{
iDelayx100 = iDelay * 100;
tyStartTick = clock();
i = 0;
while((clock() - tyStartTick) < iDelayx100)
{
/* _ftime(&timebuffer);
timeline = ctime(&timebuffer.time);
printf("%.19s.%-3.3hu\n",timeline,timebuffer.millitm);*/
SleepEx(iDelay,FALSE);
i++;
}
printf("\nSleep(%d) executes %d times in %d milliseconds;"
" error = %d
milliseconds",iDelay,i,iDelayx100,iDelayx100-(i*iDelay));
}
printf("\ndone\n");
_getch();
return;
}
> The accuracy of the Sleep() and SleepEX() functions have changed with
> newer processors/PCs.
Sleep waits at least for one Kernel-Clock-Interrupt-Cycle!
On single processor machine, this is normally 10-13 ms.
On multi.processor machines (and hyperthreading) this is normally 15-20 ms!
So therfor you *cannot* use Sleep to precisely wait for a short time!!!
If the clock-cacle is 12 ms, and you do Sleep(1), your thread will in
general wait for 12 ms!
If you do Sleep(13) your thread will wait 24 ms!
--
Greetings
Jochen
My blog about Win32 and .NET
http://blog.kalmbachnet.de/
On some system the duration of the sleep is taken to the next multiple of a
"tick" (15.6ms). Why this happens, and specifically why it seems to work
better on older systems, is a mystery to me.
If anybody knows about a modern chipset that works with XP, please let me
know.
Windows is not a real time OS. So Sleep will sleep for _at least_ the
specified time. There's no way to make it sleep for exactly the value
specified. The scheduler may have other ideas about when it will give you a
time slice. Of course, you might be lucky, and the your time slice just
happens to occur when your sleep ends...
Dave
One understands that there is no guarantee, and that the actual sleep time
is likely to be longer. However, I am trying to find out if there is some
predictor of this basic difference in behavior.
> Understood, but you miss my point entirely. On some chipsets/drivers the
> minimum sleep interval is a tick (15.6ms), on some others the minimum is a
> millisecond.
In general you can say (for "normal" MS-HALs):
On Multi-core/cpu systems, the default tick count is 15 ms.
On single-core (_no_ hyperthreading) systems, the default tick count is
10 ms.
You can use "timeBeginPerdiod(1)" to decrease the scheduling tick-count.
Be aware that this might have some negative side-effects if you have
many threads...
Then:
On Multi-core/cpu systems, the minimum tick count is 2 ms
On single-core (_no_ hyperthreading) systems, the minimum tick count is
1 ms.
The minimum resolution depends on the version of the HAL.
Thanks very much - that solves my problem nicely!
Still very odd that the default is different for different PCs / OSs. Any
idea why?
Arend
"Arend Hofmeyr" <ArendH...@discussions.microsoft.com> wrote in message
news:6527B1DD-989E-4D0A...@microsoft.com...
> Hi Jochen,
>
> Thanks very much - that solves my problem nicely!
>
> Still very odd that the default is different for different PCs / OSs. Any
> idea why?
Because the cheap (in terms of number of instructions/cycles to read)
high-precision timers such as rdtsc count independently on different CPUs,
so they can't be used for scheduling on SMP kernels.