OpenMP有自己的原子访问支持,但是,至少有两个理由更喜欢C ++ 11原子:它们更灵活,它们是标准的一部分。另一方面,OpenMP比C ++ 11线程库更强大。
该标准在两个不同的章节中指定了原子操作库和线程支持库。这让我相信原子访问的组件与所使用的线程库是正交的。我确实可以将C ++ 11原子和OpenMP结合起来吗?
Stack Overflow上有一个非常similar question;然而,由于其答案并未回答实际问题,因此三年来基本上没有答案。
答案 0 :(得分:10)
更新
OpenMP 5.0定义了与C ++ 11的进一步交互。其中,它表示使用以下功能可能会导致未指定的行为:
很明显,混合C ++ 11 atomics和OpenMP 5.0将导致未指定的行为。至少标准本身承诺“预计OpenMP规范的未来版本将解决[这些]功能”。
旧讨论:
有趣的是,OpenMP 4.5标准(2.13.6)对C ++ 11原子有一个相当模糊的引用,或更具体的std::memory_order
:
意图是,当C ++ 11或C ++中存在类似操作时 C11,顺序一致的原子结构具有相同的语义 作为C ++ 11 / C11中的memory_order_seq_cst原子操作。同样,a 非顺序一致的原子结构具有与之相同的语义 C ++ 11 / C11中的memory_order_relaxed原子操作。
不幸的是,这只是一个注释,没有什么可以定义他们在一起玩得很好。特别是,即使是最新的OpenMP 5.0预览版仍然将C ++ 98作为C ++的唯一规范性参考。所以从技术上讲,OpenMP甚至不支持C ++ 11 本身。
除此之外,它可能在实践中大部分时间都有效。我同意如果与OpenMP一起使用而不是C ++ 11线程,使用std::atomic
的麻烦可能性较小。但如果有任何问题,可能就不那么明显了。最糟糕的情况是原子不会以原子方式运行,即使我在想象可能发生这种情况的现实场景时也会遇到严重问题。在一天结束时,它可能不值得,最安全的是坚持使用纯OpenMP或纯C ++ 11线程/原子。
也许Hristo对此有所说明,同时请查看this answer进行更一般性的讨论。虽然有点过时了,但我担心它仍然存在。
答案 1 :(得分:3)
目前OpenMP 4.5尚未指定。在实践中,您可以在大多数编译器中使用C ++ 11原子操作和OpenMP线程,但是没有正式的保证它可以工作。
由于未指定的行为,GCC直到最近才支持C11原子(在语义上几乎与C ++ 11原子相同)和OpenMP线程。有关详细信息,请参阅https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65467。
OpenMP 5.0试图解决这个问题。规范性语言参考已更新为C11和C ++ 11。但是,这些原子和内存模型“不受支持”,这意味着实现定义。我希望OpenMP 5.0能说更多,但是定义OpenMP和ISO语言原子的交互是非常困难的。