在C++ 11和OpenMP中对非原子内存位置的原子访问?

Dan*_*ica 6 c++ atomic openmp nonatomic

与C++ 11相比,OpenMP从内存操作的角度来看是原子性的,而不是变量.这允许例如对在编译时存储在具有未知大小的向量中的整数使用原子读/写:

std::vector<int> v;

// non-atomic access (e.g., in a sequential region):
v.resize(n);
...
v.push_back(i);
...

// atomic access in a multi-threaded region:
#pragma omp atomic write // seq_cst
v[k] = ...;
#pragma omp atomic read // seq_cst
... = v[k];
Run Code Online (Sandbox Code Playgroud)

在C++ 11中,这是不可能实现的.我们可以通过放松内存模型来将原子变量作为非原子变量进行访问,但是我们无法调整原子元素的向量.

我理解为什么C++不允许通过原子内存操作访问非原子变量.但我想知道,为什么这些原因也不适用于OpenMP.

例如,在N4013中,据说"没有合理的方法将原子操作完全可移植地应用于未声明为原子的数据." OpenMP如何能够保证这种可移植性和C++不是这样?

Jef*_*eff 2

据我了解各自的标准,OpenMP比C++11在使用上有更多的限制,这使得它可以在不使用特殊类型的情况下进行移植。例如,OpenMP 4.5 表示:

如果 x 指定的存储位置不是大小对齐的(即,如果 x 的字节对齐不是 x 大小的倍数),则原子区域的行为是实现定义的。

另一方面,如果 C++11 使用std::atomic<int>,那么编译器将保证适当的对齐。在这两种情况下,都需要对齐,但 OpenMP 和 C++11 的不同之处在于由谁负责确保完成此操作。

一般来说,OpenMP 和 C++ 之间存在哲学差异,但很难一一列举。C++ 人员考虑的是对所有事物的可移植性,而 OpenMP 则针对 HPC。