Minimum Wait Time (System Time Resolution)
Author Message
Minimum Wait Time (System Time Resolution)

Why is it that the code:

DateTime a, b;
a=DateTime.Now;
b=DateTime.Now;
TimeSpan c = b-a;
Console.WriteLine(c.TotalMilliseconds);

Always results in a wait of 15.6243 versus 1 as I would expect.

I understand that this has something to do with the resolution of the system
timer.  Is there anyway to change this?

I need to do something 100 times/sec and no faster.  Using Sleep(10) still
results in a 15.6 ms wait therefore I cannot do what I need to do any faster
than 64 times per second.

Any suggestions???

DAve

Wed, 11 May 2005 02:19:38 GMT
Minimum Wait Time (System Time Resolution)
Dave;
Would it work to just go ahead and do all 100 things and then wait for
the rest of the second to pass?

Quote:
> Why is it that the code:

>     DateTime a, b;
>     a=DateTime.Now;
>     b=DateTime.Now;
>     TimeSpan c = b-a;
>     Console.WriteLine(c.TotalMilliseconds);

> Always results in a wait of 15.6243 versus 1 as I would expect.

> I understand that this has something to do with the resolution of the
system
> timer.  Is there anyway to change this?

> I need to do something 100 times/sec and no faster.  Using Sleep(10) still
> results in a 15.6 ms wait therefore I cannot do what I need to do any
faster
> than 64 times per second.

> Any suggestions???

> DAve

Wed, 11 May 2005 02:49:24 GMT
Minimum Wait Time (System Time Resolution)
No.  The start of each unit of work must be spaced by at least 10 ms and I
must do them as fast as possible.  The work takes almost no time at all.

DAve

Quote:
> Dave;
>     Would it work to just go ahead and do all 100 things and then wait for
> the rest of the second to pass?

> > Why is it that the code:

> >     DateTime a, b;
> >     a=DateTime.Now;
> >     b=DateTime.Now;
> >     TimeSpan c = b-a;
> >     Console.WriteLine(c.TotalMilliseconds);

> > Always results in a wait of 15.6243 versus 1 as I would expect.

> > I understand that this has something to do with the resolution of the
> system
> > timer.  Is there anyway to change this?

> > I need to do something 100 times/sec and no faster.  Using Sleep(10)
still
> > results in a 15.6 ms wait therefore I cannot do what I need to do any
> faster
> > than 64 times per second.

> > Any suggestions???

> > DAve

Wed, 11 May 2005 03:22:05 GMT
Minimum Wait Time (System Time Resolution)
The precision of DateTime isn't sufficient for 10 ms intervals, you need
to use high performance timers in order to measure.

C#: http://codeproject.com/useritems/highperformancetimercshar.asp
C++: http://www.mvps.org/directx/articles/selecting_timer_functions.htm

Not sure Thread.Wait is good for such low wait times, since it takes
too long to get your thread re-scheduled. It might be necessary to
busy wait in a tight loop until the time has elapsed. In pseudocode
something like:

// stop_busy_wait is the timestamp when you're done wating and
//     should proceed working again.
// now() is whatever high-performacne timer you picked from the
for (current=now(); now<stop_busy_wait; current=now())
{
// do nothing
}

Note that this will take all your CPU while waiting. (This is how most
games work)

Quote:

> No.  The start of each unit of work must be spaced by at least 10 ms and I
> must do them as fast as possible.  The work takes almost no time at all.

> DAve

> > Dave;
> >     Would it work to just go ahead and do all 100 things and then wait for
> > the rest of the second to pass?

> > > Why is it that the code:

> > >     DateTime a, b;
> > >     a=DateTime.Now;
> > >     b=DateTime.Now;
> > >     TimeSpan c = b-a;
> > >     Console.WriteLine(c.TotalMilliseconds);

> > > Always results in a wait of 15.6243 versus 1 as I would expect.

> > > I understand that this has something to do with the resolution of the
> > system
> > > timer.  Is there anyway to change this?

> > > I need to do something 100 times/sec and no faster.  Using Sleep(10)
> still
> > > results in a 15.6 ms wait therefore I cannot do what I need to do any
> > faster
> > > than 64 times per second.

> > > Any suggestions???

> > > DAve

Wed, 11 May 2005 03:59:39 GMT
Minimum Wait Time (System Time Resolution)
To use the High Performance counters in C#, see the article
HOW TO: Use QueryPerformanceCounter to Time Code in Visual C# .NET
at http://www.*-*-*.com/

Change the usage of the keyword "ref" in the system calls to "out" in the
DllImport declaration, in order to suppress some error messages about the
argument not being initialized.

These win32 APIs do not provide a way to sleep your thread.   I guess you'll
need to write a device driver to do that. I'm reasonably sure that the
device driver tools enable you to do what you want.  Also, consider the
possibility of Windows CE, which is closer to the hardware, having support
for embedded development.

If, instead, you choose to implement a tight loop hogging all the cpu,
repeatedly calling QueryPerformanceCounter, polling for the elapsed time,
consider inserting a call to "Thread.Sleep(0)" in the loop.  This allows
other code to run, and tends to smooth out the otherwise-chunky response, at
the risk of sleeping too long.  You can raise the priority of the busy-loop
thread if it turns out to sleep too long on the "sleep(0)" call.  Welcome to
the {*filter*} world of real time...

Warren

Wed, 11 May 2005 05:26:44 GMT
Minimum Wait Time (System Time Resolution)
I used the QueryPerformanceCounter and QueryPerformanceFrequency to
run a method that produces the following output showing the timing of
the method.  Some notes, make sure you run the method one time ( I
passed in a parameter to control this ) so that it gets properly JITed
before using it to get numbers like this, or you could have a large lag
time at startup of the method.

I used the Thread.Sleep(0) in the method and saw no degradation over
a 10 second run, though there were a few spots where it hit a speed
bump.

Total
Run#   Elapsed time.
1         0.01000099
2         0.02000087
3         0.03000018
4         0.04000173
5         0.05027203
6         0.06000008
7         0.07000275
8         0.08000123
9         0.09003016
10       0.1000021

Example Speed bump:
62     0.6200014
63     0.6330768
64     0.6489601
65     0.6559988
66     0.6600951

As mentioned, this did take 100% of the CPU time..
Ancillary note:  I just reran it, while dragging another window all
over the screen, which forced multiple repaints on the underlying
windows... that really messes up the entire process.

Chris R.

Quote:
> To use the High Performance counters in C#, see the article
> HOW TO: Use QueryPerformanceCounter to Time Code in Visual C# .NET
> at http://www.*-*-*.com/

> Change the usage of the keyword "ref" in the system calls to "out" in
the
> DllImport declaration, in order to suppress some error messages about
the
> argument not being initialized.

> These win32 APIs do not provide a way to sleep your thread.   I guess
you'll
> need to write a device driver to do that. I'm reasonably sure that the
> device driver tools enable you to do what you want.  Also, consider
the
> possibility of Windows CE, which is closer to the hardware, having
support
> for embedded development.

> If, instead, you choose to implement a tight loop hogging all the cpu,
> repeatedly calling QueryPerformanceCounter, polling for the elapsed
time,
> consider inserting a call to "Thread.Sleep(0)" in the loop.  This
allows
> other code to run, and tends to smooth out the otherwise-chunky
response, at
> the risk of sleeping too long.  You can raise the priority of the
busy-loop
> thread if it turns out to sleep too long on the "sleep(0)" call.
Welcome to
> the {*filter*} world of real time...

>  Warren

Wed, 11 May 2005 06:26:30 GMT
Minimum Wait Time (System Time Resolution)
It sounds to me like you'd be happier with a timer that fires every 10mS
rather than using waits.

--
Visit the C# product team at http://www.gotdotnet.com/team/csharp

This posting is provided "AS IS" with no warranties, and confers no rights.

Quote:
> Why is it that the code:

>     DateTime a, b;
>     a=DateTime.Now;
>     b=DateTime.Now;
>     TimeSpan c = b-a;
>     Console.WriteLine(c.TotalMilliseconds);

> Always results in a wait of 15.6243 versus 1 as I would expect.

> I understand that this has something to do with the resolution of the
system
> timer.  Is there anyway to change this?

> I need to do something 100 times/sec and no faster.  Using Sleep(10) still
> results in a 15.6 ms wait therefore I cannot do what I need to do any
faster
> than 64 times per second.

> Any suggestions???

> DAve

Wed, 11 May 2005 06:36:19 GMT
Minimum Wait Time (System Time Resolution)
shoot... after I sent in my previous posting, I realized something Your
problems could well be with the DateTime granularity, instead of the
Sleep granularity!  So, I tested that concept and I'm right!  Using a
high performance counter...

private void TestTime()
{
counter.Clear();
counter.Start();
counter.Stop();
Trace.WriteLine( counter.Seconds );

Quote:
}

Shows that Sleep is NOT the problem.  DateTime is.

Chris R.

Quote:
> Why is it that the code:

>     DateTime a, b;
>     a=DateTime.Now;
>     b=DateTime.Now;
>     TimeSpan c = b-a;
>     Console.WriteLine(c.TotalMilliseconds);

> Always results in a wait of 15.6243 versus 1 as I would expect.

> I understand that this has something to do with the resolution of the
system
> timer.  Is there anyway to change this?

> I need to do something 100 times/sec and no faster.  Using Sleep(10)
still
> results in a 15.6 ms wait therefore I cannot do what I need to do any
faster
> than 64 times per second.

> Any suggestions???

> DAve

Wed, 11 May 2005 06:43:38 GMT
Minimum Wait Time (System Time Resolution)
Yes, I agree, I'd tried the Timer first, in fact, but I'd tried to
wrap it around the example code with the DateTime to test the timing and
getting unsatisfactory results.  Using the performance counter that I
borrowed from your "Unsafe at any limit" article (part of my Utility
library), I was able to get extremely satisfactory results with a Timer.

Chris R.

Quote:
> It sounds to me like you'd be happier with a timer that fires every
10mS
> rather than using waits.

> --
> Visit the C# product team at http://www.gotdotnet.com/team/csharp

> This posting is provided "AS IS" with no warranties, and confers no
rights.

> > Why is it that the code:

> >     DateTime a, b;
> >     a=DateTime.Now;
> >     b=DateTime.Now;
> >     TimeSpan c = b-a;
> >     Console.WriteLine(c.TotalMilliseconds);

> > Always results in a wait of 15.6243 versus 1 as I would expect.

> > I understand that this has something to do with the resolution of
the
> system
> > timer.  Is there anyway to change this?

> > I need to do something 100 times/sec and no faster.  Using Sleep(10)
still
> > results in a 15.6 ms wait therefore I cannot do what I need to do
any
> faster
> > than 64 times per second.

> > Any suggestions???

> > DAve

Wed, 11 May 2005 07:09:40 GMT
Minimum Wait Time (System Time Resolution)
If you know WinAPI functions, you can try this way.

Use high resolution timer. You can get the reference from MSDN library at
Plateform SDK/Graphics and Multimedia Services/Windows Multimedia/Multimedia
input/Timer.

I did a project using this techniques. It usually runs at 125Hz but
sometimes at 250Hz. Its works perfect.

Hu

Quote:
> Why is it that the code:

>     DateTime a, b;
>     a=DateTime.Now;
>     b=DateTime.Now;
>     TimeSpan c = b-a;
>     Console.WriteLine(c.TotalMilliseconds);

> Always results in a wait of 15.6243 versus 1 as I would expect.

> I understand that this has something to do with the resolution of the
system
> timer.  Is there anyway to change this?

> I need to do something 100 times/sec and no faster.  Using Sleep(10) still
> results in a 15.6 ms wait therefore I cannot do what I need to do any
faster
> than 64 times per second.

> Any suggestions???

> DAve

Wed, 11 May 2005 10:03:13 GMT
Minimum Wait Time (System Time Resolution)
Thanks all for the help.  The solution I implemented is below:

All I do to use this code is as follows:

long lastTime = //The last time I did someting
long period = //some number of uSec

AccurateTimer.Wait((lastTime+period)-AccurateTimer.Now)

public class AccurateTimer
{
[DllImport("kernel32.dll")]
extern static short QueryPerformanceCounter(ref long x);

[DllImport("kernel32.dll")]
extern static short QueryPerformanceFrequency(ref long x);

[DllImport("ntdll.dll")]
extern static short NtQueryTimerResolution(ref long MinimumResolution,
ref long MaximumResolution,
ref long ActualResolution);

/// <summary>
/// Performance Counter ticks/uSec
/// </summary>

/// <summary>
/// System Timer resolution in uSec
/// </summary>

/// <summary>
/// Sets up constants
/// </summary>
static AccurateTimer()
{
//Compute the number of perf counter ticks /uSec
long x = 0;
QueryPerformanceFrequency(ref x);
pcPeruSec=(x/1000000);
//Determines the min System Timer resolution in uSec
long a=0,b=0,c=0;
NtQueryTimerResolution(ref a, ref b, ref c);
sysTimerResolution = c/10;
}

/// <summary>
/// Waits for a min period of the specified uSec
/// </summary>
/// <param name="uSec">The number of uSec to wait</param>
public static void Wait(long uSec)
{
if (uSec<=0)
return;

//The time we entered the function
long start = 0;
QueryPerformanceCounter(ref start);

//The time when we can return
long end = start+(uSec*pcPeruSec);

//Sleep it is feasible
if(uSec>sysTimerResolution)
{
}

//Busy wait (but yield the thread) until it is time to return
long now = 0;
while(now<end)
{
QueryPerformanceCounter(ref now);
}
}

/// <summary>
/// Provides the current perf counter time in uSec
/// </summary>
public static long Now
{
get
{
long x = 0;
QueryPerformanceCounter(ref x);
return x/pcPeruSec;
}
}

Quote:
}

Quote:
> Why is it that the code:

>     DateTime a, b;
>     a=DateTime.Now;
>     b=DateTime.Now;
>     TimeSpan c = b-a;
>     Console.WriteLine(c.TotalMilliseconds);

> Always results in a wait of 15.6243 versus 1 as I would expect.

> I understand that this has something to do with the resolution of the
system
> timer.  Is there anyway to change this?

> I need to do something 100 times/sec and no faster.  Using Sleep(10) still
> results in a 15.6 ms wait therefore I cannot do what I need to do any
faster
> than 64 times per second.

> Any suggestions???

> DAve

Sat, 14 May 2005 08:20:35 GMT
Minimum Wait Time (System Time Resolution)
See also a discussion of some internal high-precision win32 timers (and some
source code) at
http://www.sysinternals.com/ntw2k/info/timer.shtml

Warren

Thu, 12 May 2005 10:36:59 GMT
Minimum Wait Time (System Time Resolution)