C ++ 11原子:将它们与内存映射的I/O一起使用是否有意义? [英] C++11 atomics: does it make sense, or is it even possible, to use them with memory mapped I/O?

查看:61
本文介绍了C ++ 11原子:将它们与内存映射的I/O一起使用是否有意义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解,C volatile 以及可选的内存防护内联asm已用于在内存映射的I/O之上实现设备驱动程序.在Linux内核中可以找到几个示例.

As I understand it, C volatile and optionally inline asm for memory fence have been used for implementing a device driver on top of memory mapped I/O. Several examples can be found in Linux kernel.

如果我们忘记了未捕获的异常(如果有的话)的风险,那么用C ++ 11原子替换它们是否有意义?或者,有可能吗?

If we forget about the risk of uncaught exceptions (if any,) does it make sense to replace them with C++11 atomics? Or, is it possible at all?

推荐答案

通常,您可以用原子代替内存隔离栅,但不能用 volatile 替换,除非它与专用于隔离栅的一起使用线程间通信.

In general, you can replace memory fences with atomics, but not volatile, except where it is used together with a fence exclusively for inter thread communication.

关于内存映射的I/O,原子不能满足的原因是:

Whith regard to memory mapped I/O the reason atomics don't suffice is that:

  • volatile 确保您对程序中对该变量的所有内存访问均确实发生,并且它们(完全在单个线程中)完全按照您指定的顺序发生.
  • std :: atomic 仅保证您的程序将表现为好像那样,所有这些内存访问均会发生(根据C ++的内存模型,该模型不知道映射的内存)I/O)和-根据指定的内存顺序-好像以指定的顺序发生.
  • volatile guarantees you that all memory accesses to that variable in your program do actuall happen and that they happen (whithin a single thread) exactly in the order you specify.
  • std::atomic only guarantees that your program will behave as if all those memory accesses happen (according to C++'s memory model, which doesn't know about memory mapped I/O) and - depending on the specified memory ordering - as if they happen in the specified order.

实际上,这意味着编译器可以用一次写入(如果它们之间没有其他同步)替换对同一(非易失性)原子的连续写入,并且对读取也是如此.如果不使用读取结果,它甚至可以完全消除读取(尽管编译器可能仍必须发出内存屏障).

In practical terms that means, that the compiler can e.g. replace consecutive writes to the same (non-volatile) atomic with a single write (if there is no other synchronization in between) and the same is true for reads. If the result of the read is not used, it could even eliminate the read completely (the compiler might still have to issue a memory barrier though).

从理论上讲,如果编译器可以证明您的所有程序都返回42,则可以将其转换为一条指令,而与程序在进程中使用多少线程和原子无关.如果您的程序使用的是volatile变量,则不是这种情况.

On a more theoretical level, if your compiler can prove that all your program does is returning 42, then it is allowed to transform this into a single instruction independently of how many threads and atomics your program uses in the process. If your program uses volatile variables that is not the case.

例如本文显示了一些可能的(并且可能意外的优化),允许编译器将其应用于原子循环变量.

E.g. This paper shows a few posssible (and probably unexpected) optimizations the compiler is allowed to apply to an atomic loop variable.

这篇关于C ++ 11原子:将它们与内存映射的I/O一起使用是否有意义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆