C++--观察各种表达式与编译器使用的优化技巧

观察各种表达式的求值过程

  • 算术运算
    1,包括“+,-,*,/”,如果不考虑编辑器的优化,他们在底层的运算过程一般是:先从内存中把值拷贝到寄存器中,然后在cpu中进行相应地运算,最后再把结果送回到内存。(对于常量一般就是直接当立即数用,都不需要经过内存)
    注:’%’ 运算的符号和第一个操作数的符号一致。对于 ‘/’ 运算,有符号 / 有符号 = 有符号,无符号 / 无符号 = 无符号,但是要注意 有符号 / 无符号 这种混搭,是把有符号作无符号做处理的,即符号位当数据位处理,所以这时结果是不正确的。至于如果两个操作数都是整数那就是整除,有一个浮点数,那结果也是浮点类型。
    2,自增和自减,有前自增(减)和后自增(减),在底层,其汇编操作是把它们拆分成两部分进行的。例:a = 5 + (b++);就会等价a = 5 + b; b = b + 1;而a = 5 + (++b);就会等价 b = b + 1; a = 5 + b;

  • 关系运算和逻辑运算
    它们其实就是真与假的判断,逆向分析时对它们具体的表达式并不关心。它们对应汇编中的条件跳转指令。对于它们编译器也有优化,如 ‘&&’ 第一个表达式为假,则结果为假,表达式二就不会执行了,’||’ 第一个表达式为真,则结果为真,表达式二同样不会执行。还有三目的条件表达式,如果判断是常量,则编译器会直接知道取那个表达式的值,底层汇编就直接当一个普通表达式处理。

  • 位运算
    这是一种不可逆的运算,所以像MD5这种加密算法就是大量使用了位运算。如x & 0 = 0;根据结果0是无法推出 x的。

编译器使用的优化技巧

  • 前言
    就优化目的一般有下面这四个方向:(1)执行速度优化(2)内存存储空间优化(3)磁盘存储空间优化(4)编译时间优化。而我们一般以执行速度优化为主。编译器的工作过程:预处理->词法分析->语法分析->语义分析->中间代码生成->目标代码生成。其中,优化一般存在最后两个阶段。尤其中间代码生成阶段,这时还和具体硬件不相关,在不同硬件环境下可以通用。

  • 与设备无关的优化方案
    1,常量折叠
    x = 1 + 2; –> x = 3;
    2,常量传播
    接上例,y = x + 3; –>y = 6;
    3,减少变量
    x = i * 2;
    y = j * 2;
    if(x > y) –> if(i > j)
    4,公共表达式
    x = i * 2;
    y = i * 2;
    –>
    x = i * 2;
    y = x;
    5,复写传播
    x = a;
    y = x + c;
    –>
    y = a + c;
    6,剪去不可达分支
    if(1 > 2)
    {

    }
    –>这个语句会直接删掉
    7,顺序语句代替分支
    –>就是条件表达式所说的优化。
    8,强度削落
    用加法或移位代替乘法,用乘法或者移位代替除法。
    9,数学变换
    x = a + 0; –>x = a;
    x = a * 1; –> x = a;
    x = a * y + b * y; –> x = (a + b) * y;
    10,代码外提
    while(x > y/2)
    –>
    t = y/2;
    while(x > t)

  • 与设备相关的优化
    1,流水线优化:就是同时能处理多条指令一起执行。
    2,分支优化:…
    3,高速缓存(cache)优化:这个区域的访问速度远高于内存,所有常常把需要经常访问的数据放这里。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值