MyFPGA Forum

 找回密码
 注册
搜索
查看: 6061|回复: 2
打印 上一主题 下一主题

什么时候应该使用volatile修饰符?

[复制链接]
跳转到指定楼层
1#
发表于 2010-5-21 13:29:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
volatile修饰符告诉编译程序不要对该变量所参与的操作进行某些优化。在两种特殊的情况下需要使用volatile修饰符:第一种情况涉及到内存映射硬件(memory-mapped hardware,如图形适配器,这类设备对计算机来说就好象是内存的一部分一样),第二种情况涉及到共享内存(shared memory,即被两个以上同时运行的程序所使用的内存)。
    大多数计算机拥有一系列寄存器,其存取速度比计算机主存更快。好的编译程序能进行一种被称为“冗余装入和存储的删去”(redundant load and store removal)的优化,即编译程序会•在程序中寻找并删去这样两类代码:一类是可以删去的从内存装入数据的指令,因为相应的数据已经被存放在寄存器中;另一种是可以删去的将数据存入内存的指令,因为相应的数据在再次被改变之前可以一直保留在寄存器中。
    如果一个指针变量指向普通内存以外的位置,如指向一个外围设备的内存映射端口,那么冗余装入和存储的优化对它来说可能是有害的。例如,为了调整某个操作的时间,可能会用到下述函数:   

time_t time_addition(volatile const struct timer * t, int a),
{
         int    n
         int    x
         time_t  then
         x=O;
         then= t->value
         for (n=O; n<1O00; n++)
         {
               x=x+a ;
         }
      return t->value - then;
}

    在上述函数中,变量t->value实际上是一个硬件计数器,其值随时间增加。该函数执行1000次把a值加到x上的操作,然后返回t->value在这1000次加法的执行期间所增加的值。
    如果不使用volatile修饰符,一个聪明的编译程序可能就会认为t->value在该函数执行期间不会改变,因为该函数内没有明确地改变t->value的语句。这样,编译程序就会认为没有必要再次从内存中读入t->value并将其减去then,因为答案永远是0。因此,编译程序可能会对该函数进行“优化”,结果使得该函数的返回值永远是0。
    如果一个指针变量指向共享内存中的数据,那么冗余装入和存储的优化对它来说可能也是有害的,共享内存通常用来实现两个程序之间的互相通讯,即让一个程序把数据存到共享的那块内存中,而让另一个程序从这块内存中读数据。如果从共享内存装入数据或把数据存入共享内存的代码被编译程序优化掉了,程序之间的通讯就会受到影响。
2#
发表于 2010-7-21 11:12:49 | 只看该作者
嘿嘿...这几天天天见到的修饰符,这下终于弄懂了...
3#
发表于 2011-1-13 15:01:42 | 只看该作者
特别是在多线程(软件时),一遍是检测程序一遍是硬件操作的时候(硬件时);特别要注意的;
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|MyFPGA

GMT+8, 2024-5-3 08:04 , Processed in 0.035683 second(s), 14 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表