对 C++11 和 OpenMP 中的非原子内存位置的原子访问
Atomic access to non-atomic memory location in C++11 and OpenMP?
OpenMP与C++11相比,从内存操作而不是变量的角度来看,它使用原子性。例如,这允许对在编译时存储在未知大小的向量中的整数使用原子读/写:
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++不能呢?
据我了解各自的标准,OpenMP 的使用限制比 C++11 更多,这使得它可以在不使用特殊类型的情况下移植。 例如,OpenMP 4.5 说:
如果 x 指定的存储位置未按大小对齐(即,如果 x 的字节对齐不是 x 大小的倍数),则原子区域的行为是实现定义的。
另一方面,如果 C++11 使用 std::atomic<int>
,则编译器将保证适当的对齐方式。 在这两种情况下,都需要对齐,但 OpenMP 和 C++11 在谁负责确保完成此操作方面有所不同。
通常,OpenMP 和 C++ 之间存在哲学差异,但很难一一列举。 C++的人正在考虑一切的可移植性,而OpenMP的目标是HPC。
相关文章:
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 如何在不等待检索的情况下获取C++中的内存位置?
- 向量的内存位置不连续
- 如何根据C++在同一内存位置重新初始化 C# 中的对象(还是自动完成)?
- 常量引用的内存位置
- C++强制变量到一个固定的内存位置
- 为什么未初始化的内存位置的值给出 -842150451 的值?
- 为什么存储在内存位置的值会发生变化?
- 在特定内存位置构造 c++ 对象
- 如果不初始化结构中的向量,它会自动为空还是具有随机内存位置的值?
- 内存位置出现Microsoft C++异常:std::out_of_range
- 函数,返回变量c++占用的内存位置的大小
- 无法在 Opencv 中显示图像导致内存位置
- 从十六进制到双的转换始终导致内存位置的 std::out_of_range
- 错误 在测试.exe 0x76C9FD62时出现未经处理的异常:Microsoft C++异常:内存位置0x006FF8
- 错误:内存位置的 std::length_error
- C++不同内存位置中的默认数组值
- 为什么动态分配的两个变量的内存位置不是连续的?
- Boost.进程间内存位置
- 查找编译时构造类的内存位置