g++的思考
来源:互联网 发布:用友支票打印软件 编辑:程序博客网 时间:2024/05/16 13:06
这几天在看数据库原理时,提到了查询优化,不禁联想到编译器的优化是怎样的?
就比如在汇编中,一般a/2可以通过逻辑右移就得出结果的,这算是优化,不用经过算术指令老老实实地除。
在这情况下,(a+b)/2明显比a/2+b/2更快,那后者在编译器会优化为前者吗?这就是mark的原因。
反汇编
先来看a/2+b/2,反汇编后,去掉相关的栈操作(子程序eip进出栈),主要显示
0x08048583 <+6>: movl $0x3e8,-0xc(%ebp)
0x0804858a <+13>: movl $0x5dc,-0x8(%ebp)
0x08048591 <+20>: mov -0xc(%ebp),%eax
0x08048594 <+23>: mov %eax,%edx
0x08048596 <+25>: shr $0x1f,%edx
0x08048599 <+28>: add %edx,%eax
0x0804859b <+30>: sar %eax
0x0804859d <+32>: mov %eax,%edx
0x0804859f <+34>: mov -0x8(%ebp),%eax
0x080485a2 <+37>: mov %eax,%ecx
0x080485a4 <+39>: shr $0x1f,%ecx
0x080485a7 <+42>: add %ecx,%eax
0x080485a9 <+44>: sar %eax
0x080485ab <+46>: add %edx,%eax
而(a+b)/2,反汇编后,主要显示
0x08048583 <+6>: movl $0x3e8,-0xc(\%ebp)
0x0804858a <+13>: movl $0x5dc,-0x8(%ebp)
0x08048591 <+20>: mov -0x8(%ebp),%eax
0x08048594 <+23>: mov -0xc(%ebp),%edx
0x08048597 <+26>: add %edx,%eax
0x08048599 <+28>: mov %eax,%edx
0x0804859b <+30>: shr $0x1f,%edx
0x0804859e <+33>: add %edx,%eax
0x080485a0 <+35>: sar %eax
差不多的原理,先将局部变量入栈,然后从栈中取参进行操作,但很明显看出两者的不同,前者多了一次 /2 操作。
0x080485a2 <+37>: mov %eax,%ecx
0x080485a4 <+39>: shr $0x1f,%ecx
0x080485a7 <+42>: add %ecx,%eax
0x080485a9 <+44>: sar %eax
可见编译器并没有优化这类语句。可能因为两者不同。
(a+b)/2的确节省一次操作,节省了时间,但比a/2+b/2溢出的可能性要大,主要取决于a和b的值了,非编译器之功了。
同样a、b交换,可以
t=a;a=b;b=t;
也可以
a=b^b;b=a^b;a=a^b;
实际就是mov和xor的差异 t=a;
的汇编代码
0x080485c1 <+20>: mov -0xc(%ebp),%eax
0x080485c4 <+23>: mov %eax,-0x4(%ebp)
和 b=a^b;
的汇编代码
0x080485d9 <+44>: mov -0xc(%ebp),%eax
0x080485dc <+47>: xor %eax,-0x8(%ebp)
编译器可以转化循环、条件语句和递归函数、消除整块代码和利用目标指令集的优势让代码变得高效而简洁。
这才是编译器能做的。
mark,进一步了解可以参考:
有关整数除法的优化
关于VS编译器的优化例子(里面的例子在g++试过,汇编是不一样的)
关于软件源代码编译(就是make install那一套)
- g++的思考
- 由一个创建100G的表空间的面试题引发的思考
- 对XP下4736G的变慢问题的思考
- hylan:卸载oracle 11g时,关于计算机基础知识的思考:delete和shift+delete的区别
- 对思考的思考
- 关于思考的思考
- 关于思考的思考
- 有关思考的思考
- << 的思考
- 思考我们的思考方式
- 对无效思考的思考
- 2G、 3G、 4G、5G的区别
- 《思考的技术》的思考技术点
- 书写乃是最好的思考-----学会思考
- 大鱼思考---有关190亿$的思考
- 【思考】毕业季的纠结与思考
- 编程的思考
- const的思考
- MDA模式开发Struts Portlet
- 微信开发从入门到精通教程大全 资料大全 java和php版本;教程文档、代码、视频 微信商城实例
- 支付失败不清空购物车
- JedisPool的配置参数
- jmeter源码集成eclipse二次开发
- g++的思考
- F1V3.0-24 UI前端模块的发布及部署
- PHP两个数组合并键值
- 找出二叉搜索树第k大的节点
- RSA公钥加密算法
- 15 个 Android 通用流行框架大全
- 【算法题】最长公共子串
- thingkphp 错误 Undefined class constant 'MYSQL_ATTR_INIT_COMMAND'解决
- 图像平滑-平均滤波、高斯滤波、中值滤波——MATLAB