memory_order_relax负载vs volatile负载
memory_order_relaxed load vs volatile load
使用memory_order_relax读取atomic_uint
的值与读取volatile unsigned int
的值(假设volatile操作是原子操作)之间的区别是什么?
具体来说,让我们定义:
解决方案1
- "writer"线程写入
atomic_uint
(使用任何内存顺序限定符,从memory_order_relax到memory_order_seq_cst) - "reader"线程对相同的
atomic_uint
进行原子放松读取
解决方案2
- 写
volatile unsigned int
- "reader"线程读取该值
就其现状而言,我知道这两种情况都不能保证读取器读取写入器写入的值的能力。我试图理解的是volatile读取和轻松原子读取之间的区别。当考虑写后读一致性时,一个提供了什么而另一个没有?
我看到的唯一区别是:
- volatile操作不能在它们之间重新排序,而原子负载可以与其他原子操作一起重新排序
还有别的吗?
volatile read不能保证是原子性的。这意味着您可以读取从未写入变量的值(也永远不会被程序的任何部分写入)。例如,如果您的应用程序只将0xAAAAAAAA
或0xBBBBBBBB
写入变量,则volatile read可能产生0xAAAABBBB
。或者其他任何事情,因为标准没有指定当volatile读和写出现在不同线程中而没有其他同步方式时的行为。
我不知道标准是否说它是UB或实现定义的。我只能说有一些实现(例如MSVC 2005)将非同步易失性读/写的行为定义为扩展。
使用memory_order_relaxed
实际上为线程间通信提供了一个行为良好的volatile变量:
- volatile最终以ABI(应用程序二进制接口)来指定,它是一个外部接口;volatile是与外部世界的接口:对这样的对象的访问是可观察行为的一部分,永远不能被优化掉;
- 原子在内部语义方面被很好地指定;对象的表示不是规范的一部分;对这种对象的访问是抽象机器的一部分,有时可以被优化掉,或者在内部对进行推理(由编译器根据C/c++语义进行推理)。
相关文章:
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 数据成员SFINAE的C++17测试:gcc vs clang
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 正在VS调试器中监视映射条目
- Confusion: decltype vs std::function
- 将IBM Rhapsody模型集成到VS 2019中
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 使用VS Code和CMake Tools运行自定义命令
- 修改 VS Code 中的默认C++代码段
- 如何使用c++在VS 2019上运行SQL查询
- vs 2015 constexpr变量不恒定,但与2019相比还好吗
- 完美前进使用 std::forward vs RefRefCast
- 从VS 2015更新3更新到VS2015更新3 d后浮点计算行为不同的原因
- 具有内存顺序的原子负载存储
- VS 2015 链接错误 无法构建依赖于 libcurl 的项目
- 如何使用英特尔 PIN 捕获阵列的所有负载?
- consteval wrapper vs. source_location
- memory_order_relax负载vs volatile负载