Is the System.Diagnostics.Stopwatch class normally slow when called repeatedly? - c#

I have an application which must transmit packets at fixed intervals of 33ms +/- a few milliseconds.
So, I came up with a SpinTimer class shown below:
class SpinTimer
{
public void SpinWait(double waitTimeInSeconds)
{
if (waitTimeInSeconds < 0.0)
{
throw new ArgumentOutOfRangeException("waitTimeInSeconds", "Must be >= 0.0");
}
Stopwatch timer = new Stopwatch();
double elapsed = 0.0;
timer.Start();
do
{
elapsed = (double)timer.ElapsedTicks / (double)Stopwatch.Frequency;
} while (elapsed < waitTimeInSeconds);
}
}
However, after profiling the code, I found that the System.Diagnostics.Stopwatch.GetTimestamp() call was taking most of the execution time. Just as a note, I can't afford to have the thread sleep and context switch as this causes too much "jitter" in the output rate.
Notes about the profile run:
Thread priority was set to ThreadPriority.Highest
Process priority was set to ProcessPriorityClass.High
The original program that I wrote (in C++) accomplished the same effect using the QueryPerformanceCounter() and QueryPerformanceFrequency() functions. Should I be using these calls with PInvoke instead of the Stopwatch class? Or, is there another appropriate way to do this?
Thanks!

The stopwatch is in the diagnostics namespace. It shouldn't be used for performance level timing.
you probably want a Timer.

have you tried using a System.Windows.Threading.DispatcherTimer ?
I've created several programs with this, and never experienced any delay at all

After, some more debugging (inspired by Eric Lippert's comment), I realized that my above code was doing exactly as requested. The problem was with the calling code at a higher level of abstraction feeding it extremely long wait times.
Thanks for the suggestions to use System.Windows.Threading.DispatcherTimer and System.Timers.Timer (I gave both an up-vote); however, after testing each of these, they are limited to ~10 milliseconds of accuracy, which is just not quite good enough for my purposes. But, I did find that my "tight" loop code above is accurate to ~1 microsecond, which is more than enough for my current needs.
An additional resource that others might find helpful is this CodeProject article about increasing the Stopwatch accuracy. The main idea is to essentially reduce the likelihood that your program will endure a context switch, and thus travel through the scheduling queues wasting time.

Related

Odd behavior when trying to delay loop with Thread.Sleep(Timespan) [duplicate]

I want to call thread sleep with less than 1 millisecond.
I read that neither thread.Sleep nor Windows-OS support that.
What's the solution for that?
For all those who wonder why I need this:
I'm doing a stress test, and want to know how many messages my module can handle per second.
So my code is:
// Set the relative part of Second hat will be allocated for each message
//For example: 5 messages - every message will get 200 miliseconds
var quantum = 1000 / numOfMessages;
for (var i = 0; i < numOfMessages; i++)
{
_bus.Publish(new MyMessage());
if (rate != 0)
Thread.Sleep(quantum);
}
I'll be glad to get your opinion on that.
You can't do this. A single sleep call will typically block for far longer than a millisecond (it's OS and system dependent, but in my experience, Thread.Sleep(1) tends to block for somewhere between 12-15ms).
Windows, in general, is not designed as a real-time operating system. This type of control is typically impossible to achieve on normal (desktop/server) versions of Windows.
The closest you can get is typically to spin and eat CPU cycles until you've achieved the wait time you want (measured with a high performance counter). This, however, is pretty awful - you'll eat up an entire CPU, and even then, you'll likely get preempted by the OS at times and effectively "sleep" for longer than 1ms...
The code below will most definitely offer a more precise way of blocking, rather than calling Thread.Sleep(x); (although this method will block the thread, not put it to sleep). Below we are using the StopWatch class to measure how long we need to keep looping and block the calling thread.
using System.Diagnostics;
private static void NOP(double durationSeconds)
{
var durationTicks = Math.Round(durationSeconds * Stopwatch.Frequency);
var sw = Stopwatch.StartNew();
while (sw.ElapsedTicks < durationTicks)
{
}
}
Example usage,
private static void Main()
{
NOP(5); // Wait 5 seconds.
Console.WriteLine("Hello World!");
Console.ReadLine();
}
Why?
Usually there are a very limited number of CPUs and cores on one machine - you get just a small number if independent execution units.
From the other hands there are a number of processes and many more threads. Each thread requires some processor time, that is assigned internally by Windows core processes. Usually Windows blocks all threads and gives a certain amount of CPU core time to particular threads, then it switches the context to other threads.
When you call Thread.Sleep no matter how small you kill the whole time span Windows gave to the thread, as there is no reason to simply wait for it and the context is switched straight away. It can take a few ms when Windows gives your thread some CPU next time.
What to use?
Alternatively, you can spin your CPU, spinning is not a terrible thing to do and can be very useful. It is for example used in System.Collections.Concurrent namespace a lot with non-blocking collections, e.g.:
SpinWait sw = new SpinWait();
sw.SpinOnce();
Most of the legitimate reasons for using Thread.Sleep(1) or Thread.Sleep(0) involve fairly advanced thread synchronization techniques. Like Reed said, you will not get the desired resolution using conventional techniques. I do not know for sure what it is you are trying to accomplish, but I think I can assume that you want to cause an action to occur at 1 millisecond intervals. If that is the case then take a look at multimedia timers. They can provide resolution down to 1ms. Unfortunately, there is no API built into the .NET Framework (that I am aware of) that taps into this Windows feature. But you can use the interop layer to call directly into the Win32 APIs. There are even examples of doing this in C# out there.
In the good old days, you would use the "QueryPerformanceTimer" API of Win32, when sub milisecond resolution was needed.
There seems to be more info on the subject over on Code-Project: http://www.codeproject.com/KB/cs/highperformancetimercshar.aspx
This won't allow you to "Sleep()" with the same resolution as pointed out by Reed Copsey.
Edit:
As pointed out by Reed Copsey and Brian Gideon the QueryPerfomanceTimer has been replaced by Stopwatch in .NET
I was looking for the same thing as the OP, and managed to find an answer that works for me. I'm surprised that none of the other answers mentioned this.
When you call Thread.Sleep(), you can use one of two overloads: An int with the number of milliseconds, or a TimeSpan.
A TimeSpan's Constructor, in turn, has a number of overloads. One of them is a single long denoting the number of ticks the TimeSpan represents. One tick is a lot less than 1ms. In fact, another part of TimeSpan's docs gave an example of 10000 ticks happening in 1ms.
Therefore, I think the closest answer to the question is that if you want Thread.Sleep for less than 1ms, you would create a TimeSpan with less than 1ms worth of ticks, then pass that to Thread.Sleep().

Task.Delay(<ms>).Wait(); sometimes causing a 15ms delay in messaging system [duplicate]

I want to call thread sleep with less than 1 millisecond.
I read that neither thread.Sleep nor Windows-OS support that.
What's the solution for that?
For all those who wonder why I need this:
I'm doing a stress test, and want to know how many messages my module can handle per second.
So my code is:
// Set the relative part of Second hat will be allocated for each message
//For example: 5 messages - every message will get 200 miliseconds
var quantum = 1000 / numOfMessages;
for (var i = 0; i < numOfMessages; i++)
{
_bus.Publish(new MyMessage());
if (rate != 0)
Thread.Sleep(quantum);
}
I'll be glad to get your opinion on that.
You can't do this. A single sleep call will typically block for far longer than a millisecond (it's OS and system dependent, but in my experience, Thread.Sleep(1) tends to block for somewhere between 12-15ms).
Windows, in general, is not designed as a real-time operating system. This type of control is typically impossible to achieve on normal (desktop/server) versions of Windows.
The closest you can get is typically to spin and eat CPU cycles until you've achieved the wait time you want (measured with a high performance counter). This, however, is pretty awful - you'll eat up an entire CPU, and even then, you'll likely get preempted by the OS at times and effectively "sleep" for longer than 1ms...
The code below will most definitely offer a more precise way of blocking, rather than calling Thread.Sleep(x); (although this method will block the thread, not put it to sleep). Below we are using the StopWatch class to measure how long we need to keep looping and block the calling thread.
using System.Diagnostics;
private static void NOP(double durationSeconds)
{
var durationTicks = Math.Round(durationSeconds * Stopwatch.Frequency);
var sw = Stopwatch.StartNew();
while (sw.ElapsedTicks < durationTicks)
{
}
}
Example usage,
private static void Main()
{
NOP(5); // Wait 5 seconds.
Console.WriteLine("Hello World!");
Console.ReadLine();
}
Why?
Usually there are a very limited number of CPUs and cores on one machine - you get just a small number if independent execution units.
From the other hands there are a number of processes and many more threads. Each thread requires some processor time, that is assigned internally by Windows core processes. Usually Windows blocks all threads and gives a certain amount of CPU core time to particular threads, then it switches the context to other threads.
When you call Thread.Sleep no matter how small you kill the whole time span Windows gave to the thread, as there is no reason to simply wait for it and the context is switched straight away. It can take a few ms when Windows gives your thread some CPU next time.
What to use?
Alternatively, you can spin your CPU, spinning is not a terrible thing to do and can be very useful. It is for example used in System.Collections.Concurrent namespace a lot with non-blocking collections, e.g.:
SpinWait sw = new SpinWait();
sw.SpinOnce();
Most of the legitimate reasons for using Thread.Sleep(1) or Thread.Sleep(0) involve fairly advanced thread synchronization techniques. Like Reed said, you will not get the desired resolution using conventional techniques. I do not know for sure what it is you are trying to accomplish, but I think I can assume that you want to cause an action to occur at 1 millisecond intervals. If that is the case then take a look at multimedia timers. They can provide resolution down to 1ms. Unfortunately, there is no API built into the .NET Framework (that I am aware of) that taps into this Windows feature. But you can use the interop layer to call directly into the Win32 APIs. There are even examples of doing this in C# out there.
In the good old days, you would use the "QueryPerformanceTimer" API of Win32, when sub milisecond resolution was needed.
There seems to be more info on the subject over on Code-Project: http://www.codeproject.com/KB/cs/highperformancetimercshar.aspx
This won't allow you to "Sleep()" with the same resolution as pointed out by Reed Copsey.
Edit:
As pointed out by Reed Copsey and Brian Gideon the QueryPerfomanceTimer has been replaced by Stopwatch in .NET
I was looking for the same thing as the OP, and managed to find an answer that works for me. I'm surprised that none of the other answers mentioned this.
When you call Thread.Sleep(), you can use one of two overloads: An int with the number of milliseconds, or a TimeSpan.
A TimeSpan's Constructor, in turn, has a number of overloads. One of them is a single long denoting the number of ticks the TimeSpan represents. One tick is a lot less than 1ms. In fact, another part of TimeSpan's docs gave an example of 10000 ticks happening in 1ms.
Therefore, I think the closest answer to the question is that if you want Thread.Sleep for less than 1ms, you would create a TimeSpan with less than 1ms worth of ticks, then pass that to Thread.Sleep().

What Thread sleep method is most precise: Monitor.Wait vs System.Timer vs DispatchTimer vs Threading.Timer

What .NET object (or technique) is the most precise at launching a thread every XXX milliseconds? What are the tradeoffs?
For example:
int maxDurationMs = 1000;
while (true)
{
DateTime dt = DateTime.UtcNow;
DoQuickStuff()
TimeSpan duration1 = DateTime.UtcNow - dt;
int sleepTime = maxDurationMs - duration1.Milliseconds;
if (sleepTime > 0)
System.Threading.Thread.Sleep(sleepTime);
}
or
// CPU Intensive, but fairly accurate
int maxDurationMs = 1000;
while (true)
{
DateTime dt = DateTime.UtcNow;
DoQuickStuff()
while (true)
{
if (dt.AddMilliseconds(maxDurationMs) >= DateTime.UtcNow)
break;
}
}
Alternate methods of doing the same thing, but with varying degrees of accuracy and tradeoffs (CPU, etc)
System.Timer
DispatchTimer
System.Threading.Timer
Thread.Join
.NET 4.0 Task
Thread.Sleep()
Monitor.Wait(obj, timespan)
Multimedia Timers (thanks Brian Gideon)
Win32 High Resolution timers
Something else?
I have never actually used them myself, but Multimedia Timers are said to have the best resolution of any timer service in Windows. The .NET BCL does not have a wrapper for this timer service yet so you will have to do the P/Invoke calls yourself.
Another option might be to use Stopwatch together with some standard Thread.Sleep calls in a tight loop. I am not sure how much luck you would have with this approach, but it might be more accurate than a plain old Thread.Sleep call by itself. I have never tried it, but anything is worth a shot I suppose.
I did some experiments and I discovered that changing the thread priority to ThreadPriority.Highest made a considerable difference. It reduced the standard deviation of the interval by quite a bit on each technique I tried.
Don't use DateTime: its accuracy is limited to around 16ms on most systems. (See Eric Lippert's blog)
The most accurate method would be to have a dedicated thread running a while loop with a System.Diagnostics.Stopwatch object to count the time.
Even with the most precise and accurate timer in existance, raising an event exactly every x milliseconds is no simple task given the unpredictability of CPU time slices: I suggest looking into how games do their main loop (achieving a stable 30fps with lag compensation, for instance). A good example is OpenTK's GameWindow, specifically the RaiseUpdateFrame method.
If you want precise intervals Windows Timers are probably not what you need to be using, probably some sort of RTOS would be better suited for you.
From above link:
The Timer API was created to address problems with currently available timers... However, Windows timers are not as accurate as applications may require. Although Windows timer messages can be scheduled with millisecond accuracy, they seldom deliver that result because the accuracy of a Windows timer is dependent on the system clock and current activity. Because WM_TIMER messages are processed at a low priority, somewhat like WM_PAINT messages, they are often delayed while other messages are processed.
In my window services periodic actions i use Monitor.Wait because it releases a Thread and allows me to perform action without worrying about next "timer tick" before i finish.
With this I get +/- 1 ms precision. If everything goes right.
But if You need perfect precision that you can count on You shouldn't use .NET. Actually You shouldn't use Windows. There always is a possibility that Your process (or thread) will be postponed in execution.
The basic implementation of System.Timers.Timer object skewed approx 120 MS and caused me to skip at least one second every minute.
I am able to use the following technique to get a timer accurate within 1ms on a 1 minute interval. Shorter intervals may not be able to achieve the same accuracy (plus the overhead to DoWork() plays a part in this efficiency)
public class SystemTimerTest
{
readonly System.Timers.Timer timerRecalcStatistics;
readonly System.Diagnostics.Stopwatch stopwatchForRecalcStatistics = new System.Diagnostics.Stopwatch();
public SystemTimerTest(TimeSpan range, DataOverwriteAction action)
{
int recalculateStatisticsEveryXMillseconds = 1000;
timerRecalcStatistics = new System.Timers.Timer(recalculateStatisticsEveryXMillseconds);
timerRecalcStatistics.AutoReset = true;
timerRecalcStatistics.Elapsed += new System.Timers.ElapsedEventHandler(TimerRecalcStatisticsElapsed);
timerRecalcStatistics.Interval = recalculateStatisticsEveryXMillseconds;
timerRecalcStatistics.Enabled = true;
this.maxRange = range;
this.hashRunningTotalDB = new HashRunningTotalDB(action);
this.hashesByDate = new HashesByDate(action);
this.dataOverwriteAction = action;
}
private void TimerRecalcStatisticsElapsed(object source, System.Timers.ElapsedEventArgs e)
{
stopwatchForRecalcStatistics.Start();
Console.WriteLine("The TimerRecalcStatisticsElapsed event was raised at {0}", e.SignalTime.ToString("o"));
// DO WORK HERE
stopwatchForRecalcStatistics.Stop();
double timeBuffer = GetInterval(IntervalTypeEnum.NearestSecond, e.SignalTime) - stopwatchForRecalcStatistics.ElapsedMilliseconds;
if (timeBuffer > 0)
timerRecalcStatistics.Interval = timeBuffer;
else
timerRecalcStatistics.Interval = 1;
stopwatchForRecalcStatistics.Reset();
timerRecalcStatistics.Enabled = true;
}
}
I wonder if this lost 1 to 120ms per 1 second cycle means the CPU isn't as efficient as it could be with this implementation.

One timer, many method calls or many timers, one method call?

I'm developing an application for WinCE 5.0 on .NET CF 2.0.
I was wondering what other people see as the best solution in the following two cases:
Assume that i have 10 methods that i need to run every 50mS.
Solution 1:
Create one System.Threading.Timer that runs every 50mS and then in this callback run the above mentioned 10 methods.
Solution 2:
Create 10 System.Threading.Timer that runs every 50mS and then in each of their callbacks call one of the above methods.
Which solution do you think is best? Some of the methods are cpu intensive, others are not.
Using multiple timers makes the calls independent. That matters most with respect to exceptions. Do you want the other methods to proceed if #2 throws? Are the methods otherwise dependent on each other?
With multiple timers on a multi-core you will profit by executing on the ThreadPool.
Under Win-CE you are probably running on a single core, making part of this reasoning academic.
I don't think I'd use a Timer at all. A Timer is going to spawn a thread when it fires, which a) takes more time and b) allows for reentrancy, meaning you could be running your methods, especially if they take a while, simultaneously.
I'd spawn a single thread at startup (you define what that means - app startup, some object creation, etc) that does all the reads sequentially, does a Sleep call and then repeats.
Something along these lines:
private void Startup()
{
new Thread(WorkerProc) { IsBackground = true }
.Start();
}
private void WorkerProc()
{
int pollPeriod = 50;
while (true)
{
var et = Environment.TickCount;
// call your methods
et = Environment.TickCount - et;
var sleep = pollPeriod - et;
if (sleep < 0) sleep = 0; // always yield
Thread.Sleep(sleep);
}
}
It boils down to how accurate those methods needs to be. Calling each method in sequence (using the same timer) will not run all methods every 50ms, since each method takes time to complete.
If all methods must run every 50s: use different timers; otherwise use the same timer.
as it looks you dont depend on the order of your operations, otherwise you wouldnt ask the question.
I would prefer the "1 Timer per operation" solution. If you have an operation which is once more time consuming (lot of data whatever) at least the other operations will still get executed. But I dont know if that really helps you. It depends a lot about your needs/implementation
I would go for Solution 1, at least for your CPU intensive methods.
Then you implicitly run your methods in sequence. I assume that since your are on WinCE you don't have that many cores or that much RAM and the best trade of is to not try to run more code in parallel than necessary.
In Solution 2 you run into the risk of creating multiple thread executing your 10 methods at the same time. This might be good if you are waiting on I/O, especially network I/O.

Timer takes 10 ms more than interval

I am using a timer with interval 1 second.
But in the timer's tick event when I print the time it's always 62 or 65 ms.
I don't understand why it's taking 10 ms more.
Please can some one have look into this.
Here is the code I am using:
static int _counter;
var _timer = new System.Timers.Timer(1000);
public Form1()
{
InitializeComponent();
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
}
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine(DateTime.Now.ToString("{hh:mm:ss.fff}"));
_counter++;
if (_counter == 20)
_timer.Stop();
}
And this the output:
{01:59:08.381}
{01:59:09.393}
{01:59:10.407}
{01:59:11.421}
{01:59:12.435}
{01:59:13.449}
{01:59:14.463}
{01:59:15.477}
{01:59:16.491}
{01:59:17.505}
{01:59:18.519}
{01:59:19.533}
{01:59:20.547}
{01:59:21.561}
{01:59:22.575}
{01:59:23.589}
{01:59:24.603}
{01:59:25.615}
{01:59:26.629}
{01:59:27.643}
You need to understand that Windows is not a real-time operating system. Real-time operating systems have timer mechanisms that allow the system to make hard guarantees about when timer-initiated events occur and the overhead associated with them, and allow you to specify what behavior should occur when the deadline is missed -- for example if the previous execution took longer than the interval.
I would characterize the Windows timers as "best effort" when it comes to smaller intervals. When the interval is sufficiently long you don't notice that you aren't getting the exact interval that you requested. As you get closer and closer to the resolution of the timer (the frequency at which the timer runs), you start seeing the overhead as a percentage of the interval increase. Real-time systems take special care to minimize the software overhead, relying on more sophisticated and faster hardware solutions. The exact frequency of the Windows timer depends on the timing services that the underlying hardware provides and so may differ from system to system.
If you have real-time needs -- and doing something every 50ms may fall into that category -- then you may need to look at specialized hardware and/or a real-time OS.
It's because of the limited resolution of the system clock. The event occurs at the next system tick after the specififed time, so you will always get a few extra milliseconds.
If you need a more precise timer, you can hook into the Win32 Multimedia Timer, it is the most accurate timer (down to 1ms). Here's an article on CodeProject showing how to hook into it from C#.
First, as other people have noted, you're setting it to 1s, not 50ms.
Secondly, windows is not a real-time OS. None of the timer classes are exactly precise. All you're doing it saying that you want to wait at least this long. It takes some amount of time for everything to fire and you to end up notified that the timer has ticked once windows gets around to actually servicing the tick message.
Note that usually, in most language, sleep calls specify the minimum time after which a process would awaken. After the specified time has passed, the process is put on a queue and hopefully the scheduler activates it. But this activation may sometimes be delayed. I'm not sure about the Timer class, but I suspect it may suffer from a similar problem.
You may perhaps try to increase the priority of your process to cut down the increased time.
System.Timers.Timer is not a precise timer. Especially when system is under load it can have even bigger delays.
Also to get better accuracy in your example change time measuring code to use Stopwatch class.
static int _counter;
System.Timers.Timer _timer = new System.Timers.Timer(1000);
Stopwatch sw;
public Form1()
{
InitializeComponent();
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
sw = Stopwatch.StartNew();
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine(sw.ElapsedMilliseconds);
_counter++;
if (_counter == 20)
_timer.Stop();
sw.Reset();
sw.Start();
}
Using the system timers will always be a little longer than the value requested. This is due to the overhead of the other processes in the system.
On my system it's 14ms. Having googled; the difference is down to context thread switching delay. There's an article regarding high resolution timers here
As other responders have mentioned, Windows is not a real-time OS. If you must use windows, try using Win CE or Windows Embedded.
-S!
The accuracy of the time may depend on how many processes run. If you have that option , I would reduce the number of processes that run on your computer one by one and I mean those which consume significant cpu time,I would check if the times improve. Especially, browsers, virus scanners,programs running in the background.
The deviations are normal since they are not RTOS (real time operating systems). This is the best solution that I've found under the circumstances: Link
Program.MicroTimer microTimer = new Program.MicroTimer();
microTimer.MicroTimerElapsed += new Program.MicroTimer.MicroTimerElapsedEventHandler(OnTimedEvent);
microTimer.Interval = 1000; // Call micro timer every 1000µs (1ms)
// Can choose to ignore event if late by Xµs (by default will try to catch up)
// microTimer.IgnoreEventIfLateBy = 500; // 500µs (0.5ms)
microTimer.Enabled = true; // Start timer
System.Threading.Thread.Sleep(2000);
microTimer.Enabled = false;
Those are the code snippets. You can try them to see the values in the console.

Categories