汇编总结-第三部分_2_GNU下优化代码

通常汇编写的代码具有非常好的速度。但是难懂,所以人们就选择先编译高级语言,然后再修改汇编代码来达到优化目的。但实际上想要写的比编译器好是需要很多的练习的。对于我们这些普通的汇编使用者,就了解点简单的技巧和编译器如何优化的知识就够了。


GNU的编译器一般提供了3个级别的优化。注意优化之前先保存一遍原来的代码。

因为编译器貌似会直接把你的代码改了。。

 

编译器提供的-o –o2-o3到底做了些什么呢?

 

虽然可以直接man着看,但是还是自己抄写一遍印象深点。

优化级别1,这个级别包含-f优化功能。

-fdefer-pop

这个选项是在函数调用的时候值一直保存在堆栈中,然后一次性使用指令把这些值清空。

-fmerge-constants

将相同的常量合并。这个可能很耗时间,但是作用不大。

-fthread-jumps

编译器将经过多个跳转的情况,直接优化从第一个跳转到最后一个目标代码

-floop-optimize

优化程序中的循环,删除在循环内没有改变值的变量赋值操作。减少循环内执行的指令数量。确定如何离开循环的条件分支。

-fif-conversion

通过一些列技巧,减少或删除条件分支。

以减少if-then语句中花费的时间

-fif-conversion2

结合高级的数学特性,减少实现if-then语句所需的条件分支

-fguess-branch

利用指令周期时间重新安排指令。试图将尽可能多的指令移动到条件分支之前,最充分的利用处理器指令缓存

-fguess-branch-probability

试图确定最可能的条件分支。和延迟分支技术类似。

可能产生不同的汇编代码。

所以很多程序员会选择关闭这个选项。

-fcprop-registers

把寄存器分配给变量,编译器执行第二次检查,减少调度依赖性。删除不必要的寄存器复制操作。

 

优化级别2.这个级别包含优化级别1所有的内容

-fforce-mem

在使用变量之前,强制把存放在内存位置中的所有变量都复制到寄存器中.

对于很多指令都涉及到的变量来说,这个优化比较显著.

-foptimize-sibling-calls

将递归调用展开乘一系列一般的指令.而不是使用分支.

和指令保持为需要分支操作的单独函数调用相比,这样更快

-fstrength-reduce

对循环执行优化并且删除迭代变量.

迭代变量指的就是类似for循环中类似的i,j的东西.

-fgcsc

对生成的所有会变一眼代码执行全局通用子表达式消除例程.

简单来说组合通用代码,消除冗余代码

-fcse-follow-jumps

用来查找那些通过任何途径都不会到达的目标代码.

消除冗余

-frerun-cse-after-loop

先对循环代码优化之后,再次扫描.

确保在展开循环代码之后更进一步地优化循环代码.

-fdelete-null-pointer-checks

这个是用来检查空指针的.

编译器假设间接引用空指针将停止程序.

可能意思是增加一种机制让你用了空指针之后就自动关闭程序.

-fexpensive-optimizations

执行各种消耗昂贵的优化技术.

但是不一定保证运行时性能能提升.

反而可能一定程度上会产生负面影响.

-fregmove

重新分配mov指令中使用的寄存器,并且将其作为其他指令的做操作数,最大化捆绑寄存器使用.

-fschedule-insns

重新安排指令,消除等待数据的处理器.

比如在浮点计算的时候,

可以让处理器在等待浮点数运算结果时加载其他指令.

-fsched-interblock

跨越指令块调度指令.

非常灵活地移动指令以便等待间期完成的工作最大化.

-fcaller-saves

减少寄存器的保存.

对于多个函数一次性调用的时候.

-fpeephole2

允许进行任何计算机特定的观察孔优化

-freorder-blocks

重新安排指令块

以便改进分支操作和代码局部性

-fstrict-aliasing

强制实行高级语言的严格变量规则.

确保不在数据类型之间共享变量.

比如int和float不使用相同的内存区域.

-funit-at-a-time

指示编译器在运行优化例程之前读取整个汇编语言代码.

重新安排不消耗大量时间的代码以便优化指令缓存.

但是在编译的时候会消耗相当多的内存

-falign-functions

让函数对准内存中的特定边界的开始位置.

方便分页系统.

-falign-loops

让循环尽可能包含在一个对准内存中特定边界的开始.

也就是让循环包含在一个页面之中.

-fcrossjumping

对跨越跳转代码的处理.

组合分散在程序各处的相同代码.

可以减少程序长度,但是部一定会对性能产生优化.

 

 

优化级别3.这个整合了前面1 2级优化的全部内容

但是这个级别不能保证将改进最终代码的性能.

-finline-functions

不为函数创建单独的汇编语言代码

就像内联的优化,把函数代码包含在调用程序的代码中.

或许增加了程序的长度,但是充分利用指令缓存代码

而不是在每次函数调用时进行分支操作,可以提高性能.

我想现在编译器都默认会设置inline标志了,应该用处不大了吧.

-fweb

构建保存变量的伪寄存器网络.

伪寄存器包含数据,就像它们是寄存器一样,但是可以使用各种其他优化技术进行优化,比如cse和loop优化技术

-fgcse-after-reload

完全重新加载生成的且优化后的汇编语言代码之后执行第二次gcse优化,帮助消除不同优化代码方式创建的任何冗余段.

 

接下来还有一些简单的手动优化的方式,有些太复杂就不看了.

直接展开循环.这个就是将循环直接展开.这个对于变次数的循环可能很难做到吧.

 

循环检验条件如果是常量,那么先计算之后存放在一个变量中.(这就是通用子表达式消除...书总喜欢说的复杂些..)

 

我想使用编译器优化就能行了吧.至于其余的更深层次的优化就让汇编高手来做吧!. 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值