I'm looking for some kind of timer that has a higher resolution than the Windows default of ~15ms. I don't need a timer for time measurement but rather a timer that is able to wait X milliseconds (or call an event every X milliseconds). I know it's possible to change the Windows timer resolution with NtSetTimerResolution, but that affects all applications (which I don't want). I don't need much precision, so say if I'm looking for 2ms then 1.5ms and 2.5ms would be OK too.
Using spinners work but this obviously causes too much CPU usage. Ideas that are creative are welcome too, as long as it can get the job done.
NtSetTimerResolution and timeBeginPeriod can increase timer resoultion, but they are system wide. If anyone has good idea, please tell me.
I don't recommend that you do this. Google has modified Chrome to increase the timer frequency only when necessary, which works in most cases.
The default timer resolution on Windows is 15.6 ms – the timer interrupts 64 times per second. As the program increases the timer frequency, they increase power consumption and impair battery life. They also waste more computing power than I expected – they slow down your computer! Because of these problems, Microsoft has been telling developers for years not to increase the timer frequency.
Related
Thread.Sleep used to be tied to the system clock which clocked in at a interval at roughly 16 ms, so anything below 16ms would yield 16ms sleep. The behaviour seems to have changed some way down the line line.
What has changed? Is Thread.Sleep no longer tied to the system clock but to the high res timer? Or has the default system clock frequency increased in Windows 10?
edit:
It seems people are intersted in knowing why I use Thread.Sleep, its actually out of the scope of the question, the question is why the behavior have changed. But anyway, I noticed the change in my open source project freepie https://andersmalmgren.github.io/FreePIE/
Its a input/output emulator which is controlled by the end user using Iron python. That runs in the background. It has no natural interrupts. So I need to marshal the scripting thread so it does not starve an entire core.
Thanks to Hans Passant comment which I first missed I found the problem. It turns out Nvidias driver suit is the problem maker.
Platform Timer Resolution:Outstanding Timer Request A program or
service has requested a timer resolution smaller than the platform
maximum timer resolution. Requested Period 10000 Requesting Process
ID 13396 Requesting Process Path \Device\HarddiskVolume2\Program
Files\NVIDIA Corporation\NVIDIA GeForce Experience\NVIDIA Share.exe
This is so idiotic on so many levels. In the long run this is even bad for the environment since any computer with nvidia will use more power.
edit: Hans Comment, relevant part:
Too many programs want to mess with it, on top of the list is a free
product of a company that sells a mobile operating system. Run
powercfg /energy from an elevated command prompt to find the evildoer,
"Platform Timer Resolution" in the generated report.
The newer hardware does have a more precise timer, indeed. But the purpose of Thread.Sleep is not to be precise, and it should not be used as a timer.
It is all in the documentation:
If dwMilliseconds is less than the resolution of the system clock, the
thread may sleep for less than the specified length of time. If
dwMilliseconds is greater than one tick but less than two, the wait
can be anywhere between one and two ticks, and so on.
Also very important is that after the time elapses, your thread is not automatically run. In stead, the thread is marked as ready to run. This means that it will get time only when there are no higher priority threads that are also ready to run, and not before the currently running threads consume their quantum or get into a waiting state.
I've started the a desktop app development in C# (VS2010 .Net Fw 4.0) involving several timers.
At first, I was using System.Timers in order to send data by USB to a data bus. My point is that I need to send different periodic binary messages with several specific intervals of time such as 10ms, 20ms, 40ms, 100ms, 500ms, 1000ms ....
In each timer I have a callback function who has to send the correct data flow for each raised event.
The problem is when I have the full amount of signals working, the real interval is different than expected (3000ms raises to 3500, 100ms to 340) because when I add the 10ms to 40ms timers, the cpu is overload almost 100% and loses all the precission.
I'm working in VMWare with 2GB RAM and 2CPU cores. The Host machine is an i7-2600K CPU # 3,40GHz. I think this is no the problem.(but I think).
Before I wrote here, i was looking for an answer about how to be more exact with timing, using the most optimized resource consumption. but all I found it was unespecific.
I already knows about System.Diagnostics.Stopwatch reading about it here but this class have not events. Also System.Windows.Forms.Timer but is more imprecise, and with low resolution.
There is a good implementation here with microseconds resolution but it is the reason of my overloading CPU!
What do you think about my further steps!? I'll appreciate any help or idea you have
10% timing resolution is the goal in 10ms' interval!
I will clarify any extra info you need!
Every n*x milliseconds I perform an action where n = 0, 1, 2, ...; x is some increment.
Example - every 25 milliseconds I perform a calculation.
This action can take fewer than x seconds for each increment. As a result, I need a way in C# to wait the remaining (x - actual_time) milliseconds.
Example - if the calculation only takes 20 milliseconds, I need to wait 5 more milliseconds before re-running the calculation.
Please advise.
Thanks,
Kevin
I need a way in C# to wait the remaining (x - actual_time) milliseconds.
I presume that is C# running on Windows.
And there is your problem. Windows is not a "realtime" operating system.
The best you can do if you need millisecond-grade timing precision is to set the thread priority of your thread extremely high, and then busy-wait while querying the high performance timer (Stopwatch).
You cannot yield to another thread; the other thread could run for as much as 16 milliseconds before the operating system context switches it, and of course unless you are the highest priority thread, you have no guarantee that control is coming back to you after those 16 milliseconds are up.
Now, setting thread priority high and then busy waiting is one of the most rude things you can possibly do; essentially you will be taking control of the user's machine and not allowing them to do anything else with it.
Therefore what I would do is abandon this course of action entirely. Either, (1) consider obtaining an operating system designed for realtime process control if that is in fact your application, rather than an operating system designed for multitasking a bunch of line-of-business applications. Or (2) abandon your requirement that the action happen exactly every 25 milliseconds. Just perform the calculation once and yield the remainder of your quantum to another thread. When you get control back, see if more than 25 ms has passed since you yielded; if it has not, yield again. If it has, start over and perform the calculation.
That level of accuracy will be very difficult to achieve in a non real-time operating system like Windows. Your best bet might be to look into the multimedia timers.
The other .NET timers won't have the kind of resolution your need.
At 25ms, you may be the wrong side of the resolution of your available timers in .Net.
However - as a general solution I'd probably attempt this a different way to your "do calculation..wait until 25ms has passed" approach.
A better way may well be to use a System.Timers.Timer, on a 25ms trigger, to trigger the calculation.
var timer = new Timer(25);
timer.Elapsed += (sender, eventArgs) =>
{
DoCalc();
};
timer.Start();
In the above example, a DoCalc method will be called every 25 ms (timer resolution issues notwithstanding). You would need to consider what to do if your calculation overran it's allotted time though. As it stands, the above code would allow a second calculation to start, even if the previous had not completed.
This is a difficult one, and your options are fairly limited, as Eric Lippert and Matt Burland indicate. Basically, you can either
resort to using multimedia timers (google "multimedia timer component" or "winmm.dll"), which, although supporting time resolutions down to 0.500 ms, are no longer recommended as of Windows Vista, require Win32 interop and may bump up your CPU usage quite noticeably, or
come up with an approximated time slicing algorithm that will use the standard timer (whose resolution is usually 15.625 ms on multicore desktops), dynamically varying the timer interval upon each tick based on the difference of desired and actual time elapsed since the last timer tick (you can measure this fairly accurately using high resolution CPU performance counters, e.g. the Stopwatch class).
The latter solution will statistically give you a 40Hz timer in your sample use case, but you'll have significant jitter due to the low resolution of the timer you are using.
This is the tradeoff, the call is yours to make.
Here's a high-precision timer I wrote. I get roughly <1ms avg precision on 25ms interval. But if Windows is busy it may come in late. It's fairly lean on CPU utilization. Feel free to use. It uses Sleep(1) when the next tick is more than 15ms away and then SpinUntil (which yields as needed) to keep CPU usage at bay. Uses .NET4 features.
Link: High Precision Timer
Is there a simple way to determine how many milliseconds I need to "Sleep" for in order to "emulate" a 2 mhz speed. In other words, I want to execute an instruction, call System.Threading.Thread.Sleep() function for an X amount of milliseconds in order to emulate 2 mhz. This doesn't need to be exact to the millisecond, but is there a ball park I can get? Some forumlate that divides the PC clock speed by the 2 mhz or something?
Thanks
A 2 MHz clock has a 500 ns period. Sleep's argument is in milliseconds, so even if you used Sleep(1), you would miss 2,000 cycles.
Worse, Sleep does not promise that it will return after X milliseconds, only that it will return after at least X milliseconds.
Your best bet would be to use some kind of Timer with an event that keeps the program from consuming or producing data too quickly.
For the user, a pause of less than 100 ms or so will generally be imperceptible. Based on that, instead of attempting to sleep after each instruction, you'd be much better off executing for something like 50 ms, then sleeping for an appropriate length of time, then executing for another 50 ms.
Also note, however, that most processors with a 2 MHz clock (e.g. a Z80) did not actually execute 2 million instructions per second. A 2 MHz Z80 took a minimum of four processor clocks to fetch one instruction giving a maximum instruction rate of 500 KHz.
Note that sleeping is not at all a good proxy for running code on a less capable CPU. There are many things that affect computational performance other than clock rate. In many cases, clock rate is a second or third (or 10'th) order determinate of computational performance.
Also note that QueryPerformanceCounter() while high resolution is expensive on most systems (3000 to 5000 CPU clocks in many cases). The reason is that it requires a system call and several reads from the HPET in the system's south bridge. (note, this varies by system).
Could you help us better understand what you are trying to do?
As I mentioned in my comment on James Black's answer: do not poll a timer call (like QPC or the direct X stufF). Your thread will simply consume massive amounts of CPU cycles and not let ANY thread at a lower priority run, and will eat up most of the time at its priority. Note that the NT Scheduler does adjust thread priorities. This is called 'boosting'. If your thread is boosted and hits one of your polling loops, then it will almost assuredly cause perf problems. This is very bad behavior from a system perspective. Avoid it if at all possible.
Said another way: Windows is a mult-tasking OS and users run lots of things. Be aware that your app is running in a larger context and its behavior can have system wide implications.
The problem you will have is that the minimum sleep on windows seems to be about 20-50ms, so though you may put that you want to sleep for 1ms, it will wake up later, due to the fact that other processes will be running, and the time slice is quite large.
If you must have a small time such as 500ns (1/2e06 * 1000) then you will want to use DirectX, as it has a high-resolution timer, so that you can just loop until the pause is done, but, you will need to take over the computer, not allow other processes to interrupt what is going on.
I am using the code below
Thread.Sleep(5);
at the end of a while loop. To try and get a 5ms delay between iterations.
Sometimes it sleeps for 16ms. This I understand and accept, since it depends on when the CPU gets around to servicing the thread. However once it has woken the next iteration it seems to wake immediately after the sleep call (I am logging with timestamps). Is there a problem with using such a short sleep interval that it is treated as zero?
Your problem is like that on most modern machines, DateTime.UtcNow has a resolution of about 10-15ms (though I see the documentation says it's about 10ms since NT 3.5). If you want higher resolution timing, see the Stopwatch class, specifically Stopwatch.GetTimestamp().
Also note that Stopwatch will only use the high-resolution timers if they are available (Stopwatch.IsHighResolution will tell you at run-time). If not, it falls back to DateTime.UtcNow.Ticks.
Most likely, the problem is simply that your timer has limited resolution. If it only updates, say, every 10ms, you're going to see the same timestamp on some iterations, even if 5ms have passed.
Which timer are you using to generate your timestamps?
If I remember correctly NT time slicing, which was introduced in the NT kernel and was still active in the same way as of XP, operates right around the 5ms mark. We were building a realtime application and ran in to that problem. You will not be able to consistently get a 5ms sleep time. What we found was that you will sometimes get 10 - 16 ms, sometimes no ms and occasionally yet rarely get 5 ms.
I was doing these tests around 5 years ago though so things may have changed since then.
What sort of system are you running this on? Small intervals can depend on the processor and how high a resolution it supports. I ran an app on a handheld once where the resolution of the timer itself was 16ms. So it may be hardware related. Try increasing the time period to say 30ms and see if it works then.