关于c ++:混合C ++ 11 atomics和OpenMP

Mixing C++11 atomics and OpenMP

OpenMP对原子访问有自己的支持,但是,至少有两个理由更喜欢C++ 11原子:它们更灵活,它们是标准的一部分。另一方面,OpenMP比C++ 11线程库更强大。

该标准在两个不同的章节中指定了原子操作库和线程支持库。这使我相信原子访问的组件与所使用的线程库是正交的。我真的可以结合C++ 11原子和OpenMP吗?

关于堆栈溢出有一个非常相似的问题;但是,由于它的答案没有回答实际的问题,它基本上已经三年没有回答了。


更新:

OpenMP 5定义了与C++ 11的交互。此外,它还表示,使用以下功能可能导致未指定的行为:

  • 数据依赖顺序:原子和内存模型
  • 添加到标准库
  • C++ 11库

显然,混合C++ 11原子和OpenMP 5会导致未指定的行为。至少标准本身承诺"未来版本的OpenMP规范将解决这些特性"。

老讨论:

有趣的是,OpenMP 4.5标准(2.136)有一个相当模糊的引用C++ 11原子,或更具体的EDCX1〔0〕:

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.

不幸的是,这只是一个提示,没有什么可以定义他们在一起玩得很好。特别是,即使是最新的OpenMP 5预览,仍然引用C++ 98作为C++唯一的规范引用。从技术上讲,OpenMP甚至不支持C++ 11本身。

除此之外,它可能在实践中的大部分时间都会起作用。我同意使用EDCOX1,1,如果与OpenMP一起使用,比C++ 11线程有更少的麻烦。但如果有什么问题,可能就不那么明显了。最坏的情况是原子不原子运行,即使我有严重的困难想象一个现实的情况下,这可能发生。在一天结束时,它可能不值得,最安全的事情是坚持纯OpenMP或纯C++ 11线程/原子。

也许赫里斯托对此有话要说,同时,看看这个答案,进行更广泛的讨论。虽然有点过时,但恐怕它仍然有效。


OpenMP 4.5目前未对此进行详细说明。在实践中,可以在大多数编译器中使用OpenMP线程的C++ 11原子操作,但没有正式的保证它将工作。

由于未指定的行为,GCC不支持C11原子(这在语义上与C++ 11原子)几乎相同,直到最近才打开OpenMP线程。参见https://gcc.gnu.org/bugzilla/show_bug.cgi?详情见ID=65467。

OpenMP5.0试图解决这个问题。规范的语言引用被更新到C11和C++ 11。然而,来自这些的原子和内存模型"不受支持",这意味着定义了实现。我希望OpenMP5.0能说得更多,但是要定义OpenMP和ISO语言原子的交互是非常困难的。