Is there any std::chrono thread safety guarantee even with multicore context?
Asked Answered
O

2

16

First, I'm assuming that calling any function of std::chrono is guaranteed to be thread-safe (no undefined behaviour or race conditions or anything dangerous if called from different threads). Am I correct?

Next, for example on windows there is a well known problem related to multi-core processors that force some implementations of time related systems to allow forcing a specific core to get any time information.

What I want to know is:

  1. using std::chrono, in the standard, is there any guarantee that think kind of problem shouldn't appear?
  2. or is it implementation defined
  3. or is there an explicit absence of guarantee that imply that on windows you'd better get time always from the same core?
Oxley answered 5/6, 2012 at 9:9 Comment(4)
That KB article describes a hardware problem. It has nothing to do with Windows specifically. The same issue will occur on any OS which uses that hardware timer. And no, there's nothing in the C++ standard saying "this class is allowed to behave badly if you run your code on rare defective hardware".Doenitz
My understanding is that the problem occurs only on Windows? Anyway, why removing your answer? Also, that doesn't answer all the points I ask.Oxley
Look at what the KB article says: "This operating system's behavior is by design. The performance counter adjustment is necessary when the operating system obtains unreliable data from the chipset.". It can occur on any OS. Microsoft just documents it because people have encountered it often enough there to warrant a KB article (partly because Windows is widely used, and partly because it is widely used for games, were high-resolution timers are more frequently used)Doenitz
And I removed the answer because it doesn't answer all the points you ask. I felt it was better suited as a comment :)Doenitz
G
7

Yes, calls to some_clock::now() from different threads should be thread safe.

As regards the specific issue you mention with QueryPerformanceCounter, it is just that the Windows API exposes a hardware issue on some platforms. Other OSes may or may not expose this hardware issue to user code.

As far as the C++ standard is concerned, if the clock claims to be a "steady clock" then it must never go backwards, so if there are two reads on the same thread, the second must never return a value earlier than the first, even if the OS switches the thread to a different processor.

For non-steady clocks (such as std::chrono::system_clock on many systems), there is no guarantee about this, since an external agent could change the clock arbitrarily anyway.

With my implementation of the C++11 thread library (including the std::chrono stuff) the implementation takes care to ensure that the steady clocks are indeed steady. This does impose a cost over and above a raw call to QueryPerformanceCounter to ensure the synchronization, but no longer pins the thread to CPU 0 (which it used to do). I would expect other implementations to have workarounds for this issue too.

The requirements for a steady clock are in 20.11.3 [time.clock.req] (C++11 standard)

Gio answered 4/7, 2012 at 14:1 Comment(6)
I accept this answer because it says that steady_clock should never go backward, that is exactly what I need to know in the end. However, if you could add references to the standard, that would be great. Also, I am stupid for not having asked you first, you're in boost mailing list and I'm in the middle of your book... XDOxley
The requirements for a steady clock are in 20.11.3 [time.clock.req]Gio
Does anybody know if std::chrono::steady_clock::time_point is "reasonably expected" to be as good as an atomic variable when resetting a previous value with a new one (while concurrently being read from another thread)Mariel
No, time_point is not an atomic variable, so you cannot concurrently change a value from one thread while reading from another without synchronizationGio
Wouldn't getting the clock time require a system call and therefore would not be atomic practically?Statist
Yes, it may require a system call, but the OS can use a mutex internally to ensure that there are no thread safety issuesGio
N
-2

I honestly believe that this question is fully answered by the follow statement: There is no guarantee that an implementation will not have platform-specific bugs. It's all supposed to work perfectly, but sometimes for some reason or another it doesn't. Nobody can promise you that it will do what you want, but it is supposed to work.

Nashoma answered 6/6, 2012 at 8:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.