处理易失性内存位置时,编译器必须遵循哪些规则? [英] What Rules does compiler have to follow when dealing with volatile memory locations?

查看:108
本文介绍了处理易失性内存位置时,编译器必须遵循哪些规则?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道当从由多个线程或进程写入的内存位置读取时,应该为该位置使用 volatile 关键字,如下面的某些情况,但是我想知道更多关于什么限制它真的使编译器,并且基本上编译器必须遵循什么规则处理这种情况下,并且有任何特殊情况下,尽管同时访问一个内存位置volatile关键字可以被程序员忽略。

  volatile SomeType * ptr = someAddress; 
void someFunc(volatile const SomeType& input){
// function body
}


volatile 的一个特殊和非常常见的优化是将内存中的值缓存到一个寄存器,并使用寄存器进行重复访问(因为这比每次返回到内存要快得多)。



而是编译器必须每次从内存中提取值(从Zach提示,我应该说每次



一系列写入也不能使用寄存器,并且只能稍后写入最终值:每次写入必须推送到内存。



为什么这很有用?在某些架构上,某些IO设备将其输入或输出映射到存储器位置(即,写入该位置的字节实际上在串行线上出去)。如果编译器将这些写入中的一些重定向到仅偶尔刷新的寄存器,则大多数字节不会进入串行线。不好。使用 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
}

解决方案

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).

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.

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.

这篇关于处理易失性内存位置时,编译器必须遵循哪些规则?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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