In using Stopwatch.GetTimestamp() we find that if you record the return value and then continue calling it and comparing to the previous return value, it will eventually but unpredictably return a value less than the original.
Is this expected behavior?
The purpose of doing this in the production code is to have a microsecond accurate sytem time.
The technique involves calling DateTime.UtcNow and also calling Stopwatch.GetTimestamp() as originalUtcNow and originalTimestamp, respectively.
From that point forward, the application simply calls Stopwatch.GetTimestamp() and using Stopwatch.Frequency it calculates the difference from the originalTimestamp variable and then adds that difference to the originalUtcNow.
Then, Voila...an efficient and accurate microsecond DateTime.
But, we find that sometimes the Stopwatch.GetTimestamp() will return lower number.
It happens quite rarely. Our thinking is to simply "reset" when that happens and continue.
HOWEVER, it makes us doubt the accuracy of the Stopwatch.GetTimestamp() or suspect there is a bug in the .Net library.
If you can shed some light on this, please do.
FYI, based on the current timestamp value, the frequence, and the long.MaxValue it appears unlikely that it will roll over during our lifetime unless it's a hardware issue.
EDIT: We're now calculating this value "per thread" and then "clamping it" to watch for jumps between cores to reset it.
It's possible that you get the jump in time because your thread is jumping cores. See the "note" on this page: http://msdn.microsoft.com/en-us/library/ebf7z0sw.aspx
Thanks! This follows logic since it is a multi-threaded application. And your link gives a confirmation that a hardware and BIOS issue may cause this. I give you credit for the answer. Any suggestion on how to address this? We are simply keeping "lastClockTime" and comparing, it's it's less then we reset.
@Wayne:
Environment.TickCount
apparently doesn't suffer from this issue, but it's less precise, and overflows in less than a month.We suffered from the overflow already. It was painful. And it's too far less precise for our needs. Thanks for offering, anyway.
@Groo 1) Are you sure? 2) What is the precision? Is it 1ms? Or 15.6ms? (unless you increase timer resolution)
@Eugen: no, I was wrong to comment that.
Environment.TickCount
has a resolution of ~16ms, so the only way to get better resolution is to use aQueryPerformanceCounter
(or theStopwatch
which uses this under the hood, provided that high-res counters are available on that system).