请教:volatile关键字

[复制链接]
4558|13
 楼主| L_thread 发表于 2009-6-4 22:05 | 显示全部楼层 |阅读模式
volatile&nbsp;int&nbsp;i;<br />int&nbsp;i又怎样的区别?<br /><br />
computer00 发表于 2009-6-4 22:11 | 显示全部楼层

volatile告诉编译器不要对这个变量进行代码上的优化

  
beercola 发表于 2009-6-4 23:51 | 显示全部楼层

补充下

比如:<br />volatile&nbsp;int&nbsp;i;<br />i=0;<br />i=1;<br />i=2;<br />上面的所有语句逐条执行。<br />int&nbsp;i;<br />i=0;<br />i=1;<br />i=2;<br />优化之后仅执行最后一句i=2;<br />一般对功能寄存器地址的访问加volatile修饰。
guolingho 发表于 2009-6-23 20:29 | 显示全部楼层

不优化有什么好处呢?

关注!不优化有什么好处呢?<br />我知道在进行浮点运算时,优化后的代码和不优化的代码可能存在差别(由于浮点运算存在舍入误差)。那么在整数运算时应该来说优化与否结果都会相同的那么不优化有什么作用呢?希望楼上能够做进一步的发挥哈!
zyboy 发表于 2009-6-24 10:00 | 显示全部楼层

ARM字对齐有趣现象

TCPIP协议栈一直采用的uip,感觉不是很好,想采用网上的流行的lwip协议,移植中出现了个有趣的问题,找了好半天才找到,具体不太好描述,用下面这个例子说一下(我用的是KEIL)<br /><br />在KEIL下测试结构<br /><br />testzy&nbsp;=(unsigned&nbsp;long&nbsp;*)0x0400130e;<br />*&nbsp;testzy&nbsp;=&nbsp;0x11223344;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//0x0400130C(44&nbsp;33&nbsp;22&nbsp;11)&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;testzy&nbsp;真实值变成了&nbsp;0x00001122<br /><br />反汇编看<br /><br />R0=0x11223344;<br />R1=0x0400130e;<br /><br />STR&nbsp;&nbsp;R0,[R1]&nbsp;&nbsp;;&nbsp;显然由于地址0x0400130e不是4的倍数,数据向前移动了&nbsp;(R0=0x00001122,而不是0x44332211)<br /><br />但在IAR测试下,结果又是正确的。<br /><br />不知道在ADS测试如何,不知道哪个仁兄测试看看,谢谢!<br /><br />在lwip出现问题的地方,是mem_malloc()分配内存时候错误,之所以采用自定义,我想是不是采用自带的malloc会容易产生内存碎片,<br />由于采用mem_malloc,它分配内存的地址并没有按四个字节的倍数来分,这样往导致分配好后的地址(该地址不是4的倍数)赋值的时候出错<br /><br />
wangkj 发表于 2009-6-24 10:45 | 显示全部楼层

这个关键字是对应 IO端口地址的

你这样用毫无意义。<br /><br />只有针对IO端口,才有意义。<br />IO端口随时可能变化,所以,每次回读的结果可能不一样。<br />而内存单元,没有写,回读的内容是一致的,这样,编译器就可能优化掉。<br /><br />另外,有时候,这样做也可能不好使,甚至必须关闭对应的硬件cache。<br />这可能就是硬件设计的bug了。<br /><br />如果没有硬件bug,这样做,基本io就能得到正确的数据了。
TRUE_ARM 发表于 2009-6-24 11:40 | 显示全部楼层

一个例子

<br /><br />SysV.Delay&nbsp;=&nbsp;2;<br /><br />while(SysV.Delay)<br />{<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;//<br />&nbsp;&nbsp;&nbsp;printf(&quot;Hello.!&quot;)&nbsp;;<br />}<br /><br />//--------------------------<br />如果&nbsp;SysV.Delay&nbsp;的类型为<br />1、&nbsp;&nbsp;BYTE&nbsp;类型,在ADS&nbsp;中有可能是死循环,结果就像&nbsp;while(1)<br />2、&nbsp;&nbsp;volatile&nbsp;BYTE&nbsp;类型&nbsp;,不会是死循环,原因就是每次循环都会<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;读取&nbsp;SysV.Delay&nbsp;变量,当外部程序把SysV.Delay&nbsp;清零的&nbsp;时候<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;就会退出这个循环。<br /><br />
Fe_ARM 发表于 2009-6-24 17:29 | 显示全部楼层

抑制编译器优化,直接从内存地址取数

抑制编译器优化,直接从内存地址取数
guolingho 发表于 2009-6-29 20:57 | 显示全部楼层

明白

表明该地址变量可能被外部修改,编译器不做优化。而使得外部变量修改是在该处能够反映该变量的修改!
philofly 发表于 2009-6-29 21:30 | 显示全部楼层

看了半天,只有老王说到点子上了

核心就是cache啊,valotile这个关键字就是为cache设计的啊
聆风 发表于 2009-6-30 09:08 | 显示全部楼层

在keil c51中一样要用volatile关键字.

51单片机没有cache
wangkj 发表于 2009-6-30 09:16 | 显示全部楼层

我说的是两个问题

一个是软件优化问题,另外一个是硬件设计问题。<br />这两个等可能造成读取数据错误。<br /><br />解决方案也是两个方面,<br />一个是加这个关键字,另外一个就是禁用cache。<br /><br />测试成功后,可以考虑打开cache测试,如果正常,说明硬件设计没有bug。<br /><br />voliate&nbsp;关键字,如果用不用都行,说明没有优化。
guolingho 发表于 2009-7-11 10:50 | 显示全部楼层

最近写了一个程序,确实感觉volatile关键字太有用了。不容忽

最近写了一个程序,确实感觉volatile关键字太有用了。不容忽视!<br />尤其是中断和主程序公用的变量,必须声明称volatile标识的,否则可能会使得编译器优化不能正确的优化!<br />如连续执行<br />A&nbsp;*=&nbsp;3;&nbsp;&nbsp;<br />A&nbsp;*=&nbsp;4;<br />有Volatile标识的代码编译结果为<br />&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;*=&nbsp;2;<br />&nbsp;&nbsp;08002A1C&nbsp;&nbsp;9800&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R0,&nbsp;[SP,&nbsp;#0]<br />&nbsp;&nbsp;08002A1E&nbsp;&nbsp;2102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOVS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R1#0x2<br />&nbsp;&nbsp;08002A20&nbsp;&nbsp;4348&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MULS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R0,&nbsp;R1,&nbsp;R0<br />&nbsp;&nbsp;08002A22&nbsp;&nbsp;9000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R0,&nbsp;[SP,&nbsp;#0]<br />&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;*=&nbsp;3;<br />&nbsp;&nbsp;08002A24&nbsp;&nbsp;9800&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R0,&nbsp;[SP,&nbsp;#0]<br />&nbsp;&nbsp;08002A26&nbsp;&nbsp;2103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOVS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R1#0x3<br />&nbsp;&nbsp;08002A28&nbsp;&nbsp;4348&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MULS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R0,&nbsp;R1,&nbsp;R0<br />&nbsp;&nbsp;08002A2A&nbsp;&nbsp;9000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R0,&nbsp;[SP,&nbsp;#0]<br />也就是每次都从堆栈取数据,运算后,然后存入堆栈。没有任何的优化,最大限度的遵循了编程者自己的意思。<br /><br />没有Volatile标识的代码编译结果为<br />&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;*=&nbsp;2;<br />&nbsp;&nbsp;08002A1A&nbsp;&nbsp;2002&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOVS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R0#0x2<br />&nbsp;&nbsp;08002A1C&nbsp;&nbsp;4344&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MULS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R4,&nbsp;R0,&nbsp;R4<br />&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;*=&nbsp;3;<br />&nbsp;&nbsp;08002A1E&nbsp;&nbsp;2003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOVS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R0#0x3<br />&nbsp;&nbsp;08002A20&nbsp;&nbsp;4344&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MULS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R4,&nbsp;R0,&nbsp;R4<br />没有任何的堆栈存取操作,都被优化成寄存器内执行。<br /><br />另外&nbsp;TRUE_ARM&nbsp;兄遇到的问题我也遇到了,确实是这样的,在Debug版本下没有死循环,但是在&nbsp;优化的版本下就有死循环了,编译器认为该循环控制变量没有被修改,而被优化掉,导致死循环。<br />
511 发表于 2009-7-12 09:32 | 显示全部楼层

举得例子很好

  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

8

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部