What Rules does compiler have to follow when dealing with volatile memory locations?(编译器在处理易失性内存位置时必须遵循哪些规则?)
问题描述
我知道当从多个线程或进程写入的内存位置读取时,volatile 关键字应该用于该位置,如下面的某些情况,但我想了解更多有关哪些限制的信息它真的对编译器有用吗?基本上编译器在处理这种情况时必须遵循什么规则,是否存在任何例外情况,尽管同时访问内存位置,但程序员可以忽略 volatile 关键字.
I know when reading from a location of memory which is written to by several threads or processes the volatile keyword should be used for that location like some cases below but I want to know more about what restrictions does it really make for compiler and basically what rules does compiler have to follow when dealing with such case and is there any exceptional case where despite simultaneous access to a memory location the volatile keyword can be ignored by programmer.
volatile SomeType * ptr = someAddress;
void someFunc(volatile const SomeType & input){
//function body
}
推荐答案
volatile 排除的一个特殊且非常常见的优化是将内存中的值缓存到寄存器中,并使用注册重复访问(因为这比每次返回内存要快得多).
A particular and very common optimization that is ruled out by volatile is to cache a value from memory into a register, and use the register for repeated access (because this is much faster than going back to memory every time).
相反,编译器必须每次都从内存中获取值(从 Zach 那里得到一个提示,我应该说每次"都受序列点的限制).
Instead the compiler must fetch the value from memory every time (taking a hint from Zach, I should say that "every time" is bounded by sequence points).
写入序列也不能使用寄存器,并且只能稍后再写回最终值:每次写入必须被推送到内存中.
Nor can a sequence of writes make use of a register and only write the final value back later on: every write must be pushed out to memory.
为什么这很有用?在某些架构上,某些 IO 设备将其输入或输出映射到内存位置(即写入该位置的字节实际上在串行线路上输出).如果编译器将其中一些写入重定向到仅偶尔刷新的寄存器,则大多数字节不会进入串行线路.不好.使用 volatile 可以防止这种情况发生.
Why is this useful? On some architectures certain IO devices map their inputs or outputs to a memory location (i.e. a byte written to that location actually goes out on the serial line). If the compiler redirects some of those writes to a register that is only flushed occasionally then most of the bytes won't go onto the serial line. Not good. Using volatile prevents this situation.
这篇关于编译器在处理易失性内存位置时必须遵循哪些规则?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:编译器在处理易失性内存位置时必须遵循哪些规则?
基础教程推荐
- 非静态 const 成员,不能使用默认赋值运算符 2022-10-09
- 为什么 typeid.name() 使用 GCC 返回奇怪的字符以及如 2022-09-16
- 为什么派生模板类不能访问基模板类的标识符? 2021-01-01
- GDB 显示调用堆栈上函数地址的当前编译二进制文 2022-09-05
- 初始化列表*参数*评估顺序 2021-01-01
- CString 到 char* 2021-01-01
- 为什么 RegOpenKeyEx() 在 Vista 64 位上返回错误代码 2021-01-01
- 通过引用传递 C++ 迭代器有什么问题? 2022-01-01
- 如果我为无符号变量分配负值会发生什么? 2022-01-01
- 我应该对 C++ 中的成员变量和函数参数使用相同的名称吗? 2021-01-01
