Mixing C++11 atomics and OpenMP - c++

OpenMP has its own support for atomic access, however, there are at least two reasons for preferring C++11 atomics: they are significantly more flexible and they are part of the standard. On the other hand, OpenMP is more powerful than the C++11 thread library.
The standard specifies the atomic operations library and the thread support library in two distinct chapters. This makes me to believe that the components for atomic access are kind of orthogonal to the thread library used. Can I indeed combine C++11 atomics and OpenMP?
There is a very similar question on Stack Overflow; however, it has been basically unanswered for three years, since its answer does not answer the actual question.

Update:
OpenMP 5.0 defines the interactions to C++11 and further. Among others, it says that using the following features may result in unspecified behavior:
Data-dependency ordering: atomics and memory model
Additions to the standard library
C++11 library
So clearly, mixing C++11 atomics and OpenMP 5.0 will result in unspecified behavior. At least the standard itself promises that "future versions of the OpenMP specification are expected to address [these] features".
Old discussion:
Interestingly, the OpenMP 4.5 standard (2.13.6) has a rather vague reference to C++11 atomics, or more specific std::memory_order:
The intent is that, when the analogous operation exists in C++11 or
C11, a sequentially consistent atomic construct has the same semantics
as a memory_order_seq_cst atomic operation in C++11/C11. Similarly, a
non-sequentially consistent atomic construct has the same semantics as
a memory_order_relaxed atomic operation in C++11/C11.
Unfortunately this is only a note, there is nothing that defines that they are playing nicely together. In particular, even the latest OpenMP 5.0 preview still refers to C++98 as the only normative reference for C++. So technically, OpenMP doesn't even support C++11 itself.
That aside, it will probably work most of the time in practice. I would agree that using std::atomic has less potential for trouble if used together with OpenMP than C++11 threading. But if there is any trouble, it may not be as obvious. Worst case would be a atomic that doesn't operate atomically, even though I have serious trouble imagining a realistic scenario where this may happen. At the end of the day, it may not be worth it and the safest thing is to stick with pure OpenMP or pure C++11 thread/atomics.
Maybe Hristo has something to say about this, in the mean time check out this answer for a more general discussion. While a bit dated, I'm afraid it still holds.

This is currently unspecified by OpenMP 4.5. In practice, you can use C++11 atomic operations with OpenMP threads in most compilers, but there is no formal guarentee that it will work.
Because of the unspecified behavior, GCC did not support C11 atomics (which are nearly identical in semantics to C++11 atomics) and OpenMP threads until recently. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65467 for details.
OpenMP 5.0 made an attempt to address this. The normative language references were updated to C11 and C++11. However, the atomics and memory model from these is "not supported", which means implementation-defined. I wish OpenMP 5.0 said more but it is extremely difficult to define the interaction of OpenMP and ISO language atomics.

Related

Is combining std::execution and OpenMP advisable?

I use OpenMP since some time now. Recently, on a new project, I choose to use c++17, for some features.
Because of that, I have been concerned by std::execution which allow to parallelize algorithms. That seems really powerful and elegant, But their are a lot of feature of OpenMP really useful that are not easy to use with algorithms (barrier, SIMD, critical, etc..).
So I think to mix the std::execution::par (or unseq_par) with OpenMP. Is it a good idea, or should i stay only with OpenMP?
Unfortunately this is not officially supported. It may or may not work, depending on the implementation, but it is not portable.
Only the most recent version, OpenMP 5.0, even defines the interaction with C++11. In general, using anything from C++11 and forward "may result in unspecified behavior". While future versions of the OpenMP specification are expected to address the following features, currently their use may result in unspecified behavior.
Alignment support
Standard layout types
Allowing move constructs to throw
Defining move special member functions
Concurrency
Data-dependency ordering: atomics and memory model
Additions to the standard library
Thread-local storage
Dynamic initialization and destruction with concurrency
C++11 library
While C++17 and its specific high-level parallelism support is not mentioned, it is clear from this list, that it is unsupported.

Why shared_timed_mutex is defined in c++14, but shared_mutex in c++17?

C++11 introduced std::mutex and its extended version - std::timed_mutex.
However, in c++14 we have std::shared_timed_mutex, but its 'parent', the std::shared_mutex is going to be added in c++17.
Is there any reasonable explanation for that?
If I'm not going to use 'timed' functionality of std::shared_timed_mutex, is it going to be worse (slower, consuming more resources) than proposed std::shared_mutex?
Shared mutex originally had timing in it, and was called shared_mutex.
An implementor (msvc iirc) noted they could implement it "cheaper" without timing. In particular, SRWLOCK is an existing primitive on windows that is sufficient to implement shared mutex, but timed requires extra machinery. (Via #t.c.). (However, I believe it isn't just easier because already written, but also fundamentally more expensive, at least on x86/64 windows)
It was too late to add a new type to the standard, but not too late to rename it.
So it was renamed to shared_timed_mutex, and the untimed version added in next standard.
Here is at least one of the papers involved in the rename.
We propose to rename shared_mutex to shared_timed_mutex:
(a) for consistency with the other mutexes (fixing naming inconsistency);
(b) to leave room for a shared_mutex which can be more efficient on some platforms than shared_timed_mutex.

What are the Implications of using _GLIBCXX_CXX11_ABI to use pre-5.1 C++ ABI with C++ 11/14 features?

From the manual:
In the GCC 5.1 release libstdc++ introduced a new library ABI that includes new implementations of std::string and std::list. These changes were necessary to conform to the 2011 C++ standard which forbids Copy-On-Write strings and requires lists to keep track of their size.
It is possible to use the _GLIBCXX_USE_CXX11_ABI macro to control whter the library headers use the old or the new ABI, independently of which "-std" is being used.
I'd like to know what the implications of using this "compatibility ABI" would be? I guess that the run-time performance of small-string operations will be impacted (negatively I assume), and that list-size access goes from O(1) (C11 ABI) to O(N) (compatibility ABI).
Are my guesses correct and can anyone elaborate?
Are there other implications which I have missed? What about atomics and concurrency features? Any impact?
Your first question is actually answered by the manual itself:
... the choice of ABI to use is independent of the -std option used to
compile your code... This ensures that the -std does not change the ABI, so that it is
straightforward to link C++03 and C++11 code together.
Regarding the second question, I'm afraid it's hard to generalize the impact because it depends on how your code is using the standard library. Does it copy strings a lot? How often a list size is queried? Is the code multi-threaded?
Although atomics and concurrency were introduced in C++11's standard, I'd guess that stdlib++ copy-on-write mechanism already used a variation of it anyhow. Those implementations are typically thread-safe.
Perhaps one thing you didn't directly mention is the impact on other std components that depend on those behaviors, such as list::splice

Best practice for using the 'volatile' keyword in VS2012

Since upgrading our development and build environments from VS2008 to VS2012, I am confused about the implications of using the volatile keyword in our legacy codebase (it's quite extensive as there is a much copied pattern for managing threads from the "old" days).
Microsoft has the following remarks in the VS2012 documentation:
If you are familiar with the C# volatile keyword, or familiar with the behavior of volatile in earlier versions of Visual C++, be aware that the C++11 ISO Standard volatile keyword is different and is supported in Visual Studio when the /volatile:iso compiler option is specified. (For ARM, it's specified by default). The volatile keyword in C++11 ISO Standard code is to be used only for hardware access; do not use it for inter-thread communication. For inter-thread communication, use mechanisms such as std::atomic<T> from the C++ Standard Template Library.
It goes on to say:
When the /volatile:ms compiler option is used—by default when architectures other than ARM are targeted—the compiler generates extra code to maintain ordering among references to volatile objects in addition to maintaining ordering to references to other global objects.
I take this to mean, that our existing code won't break but won't necessarily be portable (not a problem for us).
However, it does raise these questions, on which I would like some advice, if possible:
Should we remove uses of volatile qualifiers in our our code and replace with C++11 ISO Standard compliant equivalents, even though we would not port the code away from MS?
If we don't do the above, is there any downside?
I appreciate that this is not really a specific programming problem but we're embarking on some quite major refactoring and I would like to be able to offer some sensible guidelines for this work.
If you have the time for it. The benefits are not that great - C++11 atomics may allow more precise control over precisely what kind of synchronization you need, and have more clearly defined semantics, which may allow the compiler to optimize the code better.
In theory, but very very unlikely, a future version of the compiler might drop support for the MS-style volatile completely. Or one day you actually do want to port away from the MS compiler, even if you stay on Windows. If you're now doing refactoring, that might be a good time to do the work of replacing the volatiles with atomics, saving you from doing the work in the future.

atomic<int> for older c++ compilers

I am using atomic<int> in my code, but the machine in which now I'm compiling has an older g++ version which doesn't support C++11. Is there any equivalent class available on the net, so that I can use it in my code, or if not, where I can find the C++11 implementation of atomic<int> so I can copy it from there. Can this be easily done?
The proposed (i.e. unofficial) Boost.Atomic library aims to do exactly this. I don't know what state it's in currently, but it's used in the implementation of the recently (officially) accepted Boost.Lockfree library, so presumably it's usable.
EDIT — updated links, now that both Atomic and Lockfree have officially been in Boost for some time:
Boost.Atomic
Boost.Lockfree
Hans Boehm's atomic ops library is good, although it's hard to determine what's available on various platforms.
If you're OK with the LGPL, Intel TBB has what you're looking for as well (plus a lot of other stuff).
If you're only looking at GCC, then you may be able to get away with just using GCC's intrinsics (I'm not sure which version of GCC those showed up in, but they've been around for a while).
sig_atomic_t
This is an integral type of an object that can be accessed as an
atomic entity, even in the presence of asynchronous signals.
in gcc is atomic
To avoid uncertainty about interrupting access to a variable, you can use a particular data type for which access is always atomic: sig_atomic_t.