A portable high-resolution timestamp in C++
blogea.bureau14.fr
blogea.bureau14.fr
"The beauty of this is that with a precise enough timer, you also solve the multithreading issue because nothing ever happens at exactly the same time."
In the first part the author expresses a technique which narrows the window for failure, and adds a fallacy which sounds good but isn't true.
This way of thinking (narrowing windows to the point where they are probabilistically rare "enough") has been the source of many bugs.
Urs Hoezle (VP at Google) once said something I really liked which was "At a large enough scale, statistically impossible things happen every day." It is painful to accept but I've seen it in action.
http://blogs.msdn.com/b/larryosterman/archive/2004/03/30/104...
In our case, we have some additional homework to make it work on several nodes that is well beyond the scope of this post
As for multithreading, the functions are guaranteed monotonic.
"nothing happens at the same time" is a reference to the laws of physics.
> This is not a hard task. Nothing we've done above requires more than reading the documentation carefully. Attention to details like this is what makes the difference between working and rock-solid software. #frencharrogance
Um, right...
It seems like (in the long term) it would be better to push some std::chrono::steady_clock Windows patches to stdlibc++/libc++/MSVC and use this instead of re-inventing the wheel.
Hi,
Thanks for reporting this bug. We've fixed it, and the fix will be available in the next major version of VC (i.e. after 2013).
steady_clock and high_resolution_clock are now synonyms powered by QueryPerformanceCounter() converted to nanoseconds. QPC meets the Standard's requirements for steadiness/monotonicity.
Additionally, the CRT's clock() has been reimplemented with QPC. While this improves precision and conformance to the C Standard (as QPC is monotonic), we are aware that this is not completely conformant. Our CRT maintainer has chosen to avoid having clock() return CPU time advancing faster than 1 second per physical second, which could silently break programs depending on the previous behavior.
So it is expected that VS2014 should have the fixes.
On a sidenote, I've seen most of the code, if not all, posted by the OP already before while searching for the same functionality (eg the piece after "you will write your own function:" is followed by something that to me seems like a straight up copy from some FOSS project, even the comments seems to match - ok I cannot be 100% certain on this but if it's the case it would be nice to mention the source). I can't find it atm, but I am sure a C++11 clock compatible implementation using QPC has been posted on StackOverflow.
Go with timeGetTime(), remembering about calling timeBeginPeriod(1) early (usually at the beginning of application) to set minimum resolution for periodic timers to 1 ms (well, it will happen only if HW provides that much resolution), and calling timeEndPeriod(1) after you stopped working with time (usually at the end of application). Milliseconds don't give you high-resolution, but at least working in this resolution is reliable. Having us or ns garbage is hardly any better...
timeGetTime() and company though operate at the highest frequency that application has specified, and as such can be quite a drain on portable power systems (laptop etc). So when one application calls timeBeginPeriod(1) it means the laptop needs to wake up more frequently and hence is less power efficient.
QPC was buggy and is still buggy for many users out there. After 15 years Microsoft is likely getting closer to sane behavior and maybe in latest Windows 8 (8.1) and Sever 2012 (2012 R2) it really works reliably in different setups and loads (haven't tested it yet). OTOH "getting better" by sole die out of setups, where it was working incorrectly, is not really getting any better.
Viewpoint is important here. If you build your own infrastructure, you choose your HW/SW stack, can thoroughly test QPC behavior, then if it seems you go with same setup for your servers or what not [1]. But if you write software for all Windows users out there, then you don't have that much luxury. QPC is simply not good enough. You can always try with building some logic that falls back from QPC to lower resolution functions whenever odd behavior is detected, but unless you have HW/SW instances that you could test it on, then there is (high?) possibility you won't do it right, so maybe you shouldn't do it in the first place?
1 ms resolution at best should be enough in most cases. Increasing timer interrupt frequency from default 64 Hz (15.6 ms resolution) to 1000 Hz (1 ms resolution) indeed affects system behavior and can harm battery life, but it may be necessary evil. If we're talking about high-resolution time, then 1 ms resolution is simply that kind of thing for Windows (as ridiculous it may sound) if we take reliability into account. E.g. games, your multimedia applications and so on are already using timeBeginPeriod(1). Good news is that reportedly since Windows 8 the harm on battery is much less.
[1] But if you really have control over HW/SW stack for your servers, then you'll quite likely happily avoid using Windows...
How on earth are "sub-microsecond timers" supposed to be synchronized anywhere?
http://www.spectracomcorp.com/Desktopmodules/Bring2Mind/DMX/...
The units are a bit confusing but the accuracy still translates down to a handful of nanoseconds per month, I believe.
I ran into this problem trying to get better than 1us resolution for a daq system which was hooked up to custom GPS hardware which had better than 10ns resolution.
"So; to cut a long story short, if you want an accurate performance measurement you're mostly screwed. The best you can realistically hope for is an accurate time measurement; but only in some cases (e.g. when running on a single-CPU machine or "pinned" to a specific CPU; or when using RDTSCP on OSs that set it up properly as long as you detect and discard invalid values)."
[...] for Intel Core Solo and Intel Core Duo processors [...]: the time-stamp counter increments at a constant rate. The specific processor configuration determines the behavior. Constant TSC behavior ensures that the duration of each clock tick is uniform and supports the use of the TSC as a wall clock timer even if the processor core changes frequency. This is the architectural behavior moving forward.
Intel Architectures software developer system programming manual 17.13
For OS X, use mach_absolute_time, described here: https://developer.apple.com/library/mac/qa/qa1398/_index.htm...
http://en.cppreference.com/w/cpp/language/namespace
Or just '#include <stdint.h>'. C++ is TIMTOWTDI too!
Going the route `using std::uint64_t`, you'd have to do that for every basic type. Which is fine. I'd just use that in a general header that's included everywhere in a project (stdafx, or what have you). Though at that point it doesn't really matter which you pick.
Really, nothing new to see...
https://github.com/bloomberg/bde/blob/master/groups/bsl/bsls...
Component docs: http://bloomberg.github.io/bde/group__bsls__timeutil.html