- 论坛徽章:
- 0
|
本帖最后由 狗蛋 于 2011-08-26 14:41 编辑
优化有很多种。
以前看IBM的一篇文章,奔腾3访问一次主内存可能相当于执行14个加法指令.
于是:
x=100
y=fun()
....
....
print_int(x, y, z)
如果中间没有写过x或者把x传递给可能修改它的函数,那么合格的编译器就应该直接把这个x替换成常量100(而不是执行昂贵的内存读操作)
此外,现代CPU有很多寄存器,上面的y值如果一直没有被修改过,那么它完全可以放在寄存器里,到print_int的时候直接从寄存器中取值——这同样是合格的现代编译器所必须具备的能力。
随便说一句,如果print_int声明为void print_int(const &int, int, int &),那么编译器就可以知道,print_int不会修改传递给它的前两个int参数,但会修改第三个int参数——于是执行print_int之后,x、y仍然可以继续认为没有变化,而z就必须重新从主存读取了。这是const的价值之一,也是不要用强制类型转换去掉变量的const属性的理由之一。
显然,多线程环境下,如果x、y、z可能被其它线程修改,所以每次用到都要重新读取;或者,在某些机器上,外设端口和内存统一编址,那么这个地址的数据显然会随时间改变,每次都必须重新读取。这时就必须用volatile来修饰它们了。
//=============
比如全局int a;
thread1修改a为2,但这次只在寄存器中修改,之后发生线程上下文切换,到thre2,thre2读取a的数据就出问题了?
//=============
是的。编译器的确会这样优化。所以才必须有volatile关键字来明确阻止这种错误的优化。这也是编写多线程程序的难点之一。 |
|