C++11原子学:将它们与内存映射的I / O一起使用是否有意义,或者甚至可能
C++11 atomics: does it make sense, or is it even possible, to use them with memory mapped I/O?
据我了解,C volatile
和可选的内存围栏内联 asm 已用于在内存映射 I/O 之上实现设备驱动程序。 在 Linux 内核中可以找到几个示例。
如果我们忘记了未捕获异常(如果有的话)的风险,那么用 C++11 原子学替换它们是否有意义? 或者,有可能吗?
一般来说,你可以用原子代替记忆围栏,但不能用volatile
代替,除非它与专门用于线程间通信的围栏一起使用。
关于内存映射的I/O,原子学不够的原因是:
-
volatile
保证程序中对该变量的所有内存访问都会发生,并且它们完全按照您指定的顺序发生(单个线程)。 -
std::atomic
仅保证您的程序的行为就像发生所有这些内存访问一样(根据C++的内存模型,该模型不知道内存映射的I/O),并且 - 取决于指定的内存顺序 - 好像它们按指定的顺序发生。
实际上,这意味着编译器可以例如用一次写入替换对同一(非易失性)原子的连续写入(如果两者之间没有其他同步),读取也是如此。如果不使用读取结果,它甚至可以完全消除读取(编译器可能仍然必须发出内存屏障)。
在更理论的层面上,如果你的编译器可以证明你的程序所做的只是返回 42,那么允许将其转换为单个指令,而与程序在此过程中使用多少线程和原子无关。如果您的程序使用易失性变量,则情况并非如此。
编辑:例如,本文展示了一些可能的(可能是意想不到的)优化,编译器被允许应用于原子循环变量。
据我了解,读取参考文献std::atomic
旨在管理对内存的多线程访问(并发等)。但正如我所知,正如你所说,volatile
是为内存映射 I/O 和信号处理等而设计的。因此,volatile
对原子访问没有影响,如果单独使用,则不能解决多线程访问问题,例如原子。反之亦然 - 原子不提供volatile
的功能.
因此,对您的问题的简短回答是否定的。
相关文章:
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- API 返回智能指针的 std::optional 以明确指定指针可能为 null 是否有意义?
- 从头开始为应用程序创建 docker 映像是否有意义?
- 插入向量时,使用lambda的返回而不是函数的返回是否有意义?
- 将 final 关键字添加到没有基类(未派生)的类中的虚函数是否有意义
- 左移负整数为零是否有意义?
- 将可选与reference_wrapper相结合是否有意义?
- 函数返回rvalue参考是否有意义
- 将 [[noreturn]] 添加到主函数是否有意义
- 在shared_ptr的自定义删除器中检查 nullptr 是否有意义?
- 拥有一个没有构造函数的类是否有意义
- 这是否有意义,我的计算机只能并行运行4个线程
- constexpr移动构造函数是否有意义
- 为赋值编写伪代码,并希望仔细检查它是否有意义
- 在目标平台上编译 Boost 自己是否有意义
- 多层继承在C 中是否有意义
- 从 STL 容器继承并删除"新"运算符以防止由于缺少虚拟析构函数而导致未定义的行为是否有意义?
- 一元运算符关联是否有意义
- 为工厂创建一个抽象工厂是否有意义
- 返回对数组的引用是否有意义