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

8
与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];

在C++11中,这是不可能实现的。我们可以通过放宽内存模型来以某种方式访问原子变量作为非原子变量,但我们无法调整原子元素的向量大小。
我理解C++不允许通过原子内存操作访问非原子变量的原因,但我想知道,为什么这些原因对OpenMP也不适用。
例如,在N4013中,它说:"没有合理的方法完全可移植地将原子操作应用于未声明为原子的数据。" OpenMP如何保证这种可移植性,而C++不行?

2
OpenMP不必像C++那样具有可移植性,语言社区上的OpenMP实现者也同意这一点。我稍后会尝试查找详细信息。 - Jeff Hammond
1个回答

2
据我所知,OpenMP标准比C++11标准更多限制使用方式,但C++11可以在不使用特殊类型的情况下保证可移植性。例如,OpenMP 4.5规定:
如果x所指示的存储位置未对齐(即,x的字节对齐不是x大小的倍数),则原子区域的行为由实现定义。
另一方面,如果C++11使用std :: atomic ,那么编译器将保证适当的对齐方式。在两种情况下都需要对齐,但OpenMP和C++11在谁负责确保完成这项工作方面存在差异。
通常,OpenMP和C++之间存在哲学上的差异,但很难列举所有差异。 C++开发者考虑到所有的可移植性,而OpenMP则针对HPC进行了优化。

如果C++11使用std::atomic<int>,那么编译器会保证适当的对齐吗?标准在哪里规定了这一点? - osgx
如果我理解正确的话,C++11确保了原子性,并且不关心对齐方式。原子性是否依赖于适当的对齐是一个实现问题(针对特定的架构)。 - Daniel Langr
这是一个实现问题,但如果您的硬件只能为对齐的字提供原子性,则您的C++编译器无法报告std::atomic_is_lock_free,除非这些类型是对齐的,因此它将对它们进行对齐。 - Jeff Hammond

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接