C++ std::atomic能否与OpenMP一起安全使用

C++ std::atomic能否与OpenMP一起安全使用,c++,c++11,openmp,atomic,stdatomic,C++,C++11,Openmp,Atomic,Stdatomic,我目前正在尝试学习如何使用OpenMP,我有一个问题。 这样做安全吗: std::atomic<double> result; #pragma omp parallel for for(...) { result+= //some stuff; } 谢谢 编辑:我知道最简单的处理方法是使用数组,但我问这个问题是因为我很好奇,因为原子会降低并行执行的速度并且不能很好地扩展,所以最好这样做 pragma omp parallel for reduction(+:

我目前正在尝试学习如何使用OpenMP,我有一个问题。 这样做安全吗:

  std::atomic<double> result;
  #pragma omp parallel for
  for(...)
  {
  result+= //some stuff;
  }
谢谢


编辑:我知道最简单的处理方法是使用数组,但我问这个问题是因为我很好奇

,因为原子会降低并行执行的速度并且不能很好地扩展,所以最好这样做

pragma omp parallel for reduction(+:result)
for(...)
{
  double tmp=0;
  //some stuff;
  result+=tmp;
}

官方上说没有,实际上可能没有

第32页第1.7节规定:

虽然OpenMP规范的未来版本预计将解决以下功能,但当前使用这些功能可能会导致未指定的行为

  • 并发性

  • 对标准库的添加

  • C++11库

但是,根据您使用的OpenMP运行时的实现情况,它可能还可以。事实上,LLVM OpenMP运行时甚至使用它来实现一些OpenMP规范


不过,最安全的选择是坚持只使用OpenMP提供的功能。使用
std::atomic
可以做的任何事情都应该只使用OpenMP即可实现。

std::atomic
是C++11标准的多线程框架提供的工具。如果您将
std::atomic
与外部库(如OpenMP)结合使用,这些库提供了这些功能的自己的实现,您可能会遇到问题。实际上,原子库在标准中与线程库在不同的章节中指定。此外,我还没有在原子章中发现任何一个注释,说这个库只用于STD::线程。我同意@ GTCV——原子类型用C++内存模型操作,而不是线程实现。例如,如果要在OpenMP并行区域内使用C11或C++11原子,这将利用omp部分内的智能指针导致引用计数器GCC的竞争条件,用于生成错误。如果OpenMP atomics没有比使用C++11引入任何额外的复杂性,我将坚持使用前者,因为您将只依赖于OpenMP标准(您可以使用不支持C++11的编译器)。OpenMP 5.1中已修复了可能的重复:
pragma omp parallel for reduction(+:result)
for(...)
{
  double tmp=0;
  //some stuff;
  result+=tmp;
}