编译器的工作过程中可以分为几个阶段:预处理-》词法分析-》语法分析-》语义分析-》中间代码生成-》目标代码生成。其中,优化的机会一般存在于中间代码生成或目标代码生成这两个阶段。尤其是在中间代码生成阶段所做的优化,这类优化不具备设备相关性,在不同的硬件环境中都能通用。debug下, ...
编译器的工作过程中可以分为几个阶段:预处理-》词法分析-》语法分析-》语义分析-》中间代码生成-》目标代码生成。其中,优化的机会一般存在于中间代码生成或目标代码生成这两个阶段。尤其是在中间代码生成阶段所做的优化,这类优化不具备设备相关性,在不同的硬件环境中都能通用。
debug下,为了调试方便,保持原码与反汇编代码的一一对应,只是进行了很少的优化。
常见的与设备无关的优化方案有以下几种:
1、 常量折叠
当计算公式中出现多个常量进行计算,且编译器可以在编译期间计算出结果时,这样原码中所有的常量计算都将被计算结果代替
如:x=1+2结果必然是3,因此在编译期间直接生成x=3,没必要产生加法指令。
2、 常量传播
如果在程序的逻辑中,声明的变量没有修改过,而且上下文中不存在针对此变量的取地址和间接访问操作,那么这个变量就等价与常量,编译器就认为可以删除该变量,直接用常量代替。使用常量的好处是可以生成立即数寻址的目标代码,减少了内存的访问次数。
如:x=1+2;y=x+3;因为x已经计算出结果为3,所以x被常量3代替,这里直接生成y=6。
3、 公共表达式
如:x=i*2;y=i*2;这时i*2被称为公共表达式,可归并为一个:x=i*2;y=x;得到x的值之后直接赋值给y,而不会再进行一次i*2的计算。
4、 复写传播
类似常量传播,但目标变为了变量
如x=a;.......y=x+c;如果在省略号表示的代码中没有修改变量x的值,则可以直接用变量a代替x,得到y=a+c。
5、 剪支优化
如:if(1>2),因为条件永远为假,所以整个if代码块没有存在的必要,因此不会产生指令。
6、 顺序语句代替分支
如if(2>1)....else.......在编译期间就可以计算出条件的真假,因此直接生成将被执行代码块的指令,优化掉判断和不可达的代码指令。
7、 数学变换
像x=a+0;x=a-0;x=a*1;x=a/1都是代数恒等式,不会产生运算指令,直接生成x=a;
x=a*y+b*y;等价于x=(a+b)*y,所以只需一次加法一次乘法即可。
8、 代码外提
这类优化一般存在于循环中
如:while(x>y/2);如果循环体中没有修改y的值,那么没必要每次循环判定条件时,都进行一次y/2的运算,因此优化为:t=y/2;while(x>t);
第一格是C++原码,第二格是debug下反汇编代码,第三格是release反汇编下代码,重点看。
代码中的所有输入输出句都是为了防止变量被优化掉,没有其他意义。
#include <iostream>using namespace std;int main(){//=======================================常量折叠与常量传播 int a1; a1 = 1 + 1; cout << a1 << endl;//=======================================减少变量 int x1, y1, m1, n1; cin >> m1 >> n1; x1 = m1 * 2; y1 = n1 * 2; if (x1 > y1) cout <<"TRUE"<< endl;//=======================================公共表达式 int x2, y2, m2; cin >> m2 ; x2 = m2 * 2; y2 = m2 * 2; cout << x2 << y2 << endl; cin >> x2 >> y2;//=======================================复写传播 int x3, y3, a,c; cin >> a>>c; x3 = a; y3 = x3 + c; cout << x3 << y3 << endl; cin >> x3 >> y3;//=======================================剪去不可达分支(剪支优化) if (1 > 2) cout << "TRUE" << endl;//=======================================顺序语句代替分支 int a2; cin >> a2; a2 == 5 ?a2= 6 :a2= 7; cout << a2<< endl;//=======================================强度削弱 int x4, y4, a3; cin >> a3 ; x4 = a3*2; y4 = a3 / 4; cout << x4 << y4;//=======================================数学变换 int x5, y5, a4, b4; cin >> a4 >> b4; x5 = a4 * 1; y5 = a4*x5 + b4*x5; cout << x5 << y5 << endl;//=======================================代码外提 int x6, y6; cin >> x6 >> y6; while (x6 < y6 / 2) { cout << x6 << endl; x6++; }//=============================================== system("pause"); return 0;}
海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com
原标题:C++反汇编学习笔记(五)编译器(VS2013)常用的几个优化技巧(1)
关键词:
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。
|