c++ - 加载/存储宽松原子变量和普通变量有什么区别?

标签 c++ c++11 atomic memory-barriers stdatomic

正如我从一个测试用例中看到的:https://godbolt.org/z/K477q1
生成的程序集加载/存储原子松弛与普通变量相同:ldr 和 str
那么,宽松的原子变量和普通变量之间有什么区别吗?

最佳答案

不同之处在于正常的加载/存储不是。保证是无撕裂的,而轻松的原子读/写是。此外,原子保证编译器不会以类似于 volatile 的方式重新排列或优化内存访问。保证。
(C++11 之前,volatile 是滚动你自己的原子的重要组成部分。但现在它已经过时了。它在实践中仍然有效,但从不推荐:When to use volatile with multi threading? - 基本上从不。)
在大多数平台上,架构默认提供无撕裂加载/存储(对于对齐的 intlong ),因此如果加载和存储没有得到优化,它在 asm 中的工作原理相同。见 Why is integer assignment on a naturally aligned variable atomic on x86?例如。在 C++ 中,由您决定如何在源代码中访问内存,而不是依赖特定于体系结构的功能来使代码按预期工作。
如果您在 asm 中手写,那么当值保存在寄存器中与加载/存储到(共享)内存时,您的源代码就已经确定了。在 C++ 中,告诉编译器何时可以/不能保持私有(private)值是 std::atomic<T> 原因的一部分。存在。
如果您阅读了有关此主题的一篇文章,请在此处查看 Preshing 一篇:
https://preshing.com/20130618/atomic-vs-non-atomic-operations/
也可以试试 CppCon 2017 的这个演示文稿:
https://www.youtube.com/watch?v=ZQFzMfHIxng

进一步阅读的链接:

  • Read a non-atomic variable, atomically?
  • https://en.cppreference.com/w/cpp/atomic/memory_order#Relaxed_ordering
  • Causing non-atomics to tear
  • https://lwn.net/Articles/793895/
  • What is the (slight) difference on the relaxing atomic rules?其中包括指向 Herb Sutter “原子武器”文章的链接,该文章也链接在这里:
    https://herbsutter.com/2013/02/11/atomic-weapons-the-c-memory-model-and-modern-hardware/

  • 另请参阅 Peter Cordes 的链接文章:https://electronics.stackexchange.com/q/387181
    还有一篇关于 Linux 内核的相关文章:https://lwn.net/Articles/793253/
    没有撕裂只是您使用 std::atomic<T> 获得的一部分- 您还可以避免数据竞争未定义的行为。

    关于c++ - 加载/存储宽松原子变量和普通变量有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63810298/

    相关文章:

    c++ - 输出以空格分隔的列表

    c++ - GCC : literal string types in a structure 中的可能错误

    c++ - 无法调用结构内部的成员函数指针

    multithreading - Rust:使用互斥体允许从多个线程访问数据

    java - 这个线程安全的字节序列生成器有什么问题?

    c++ - 在不移动末尾的情况下删除文件中间的字节?

    c++ - 在一个进程中运行多个程序?

    memory-management - C++1y 内存管理中的大小释放功能

    C++11 原子库 std::compare_and_exchange 语义

    c++ - 为什么我不能用非引用返回类型定义 operator=?