|
|
51CTO旗下网站
|
|
移动端

1.7 汇编优化2:位操作

《ARM嵌入式系统编程与优化》第1章Linux/ARM嵌入式平台,本章介绍如何使用GCC编译器、汇编器和连接器来编写和执行独立的汇编语言程序,以及如何将一个C语言代码和汇编语言代码合起来,以验证汇编代码子程序的正确性。本节为大家介绍汇编优化2:位操作。

作者:梁元宇 译来源:机械工业出版社|2017-09-26 19:15

1.7 汇编优化2:位操作

编译器内置的代码优化器在代码上是低效的,无法在高级语言上自然表达,如那些涉及复杂的位操作、特殊算法,或者涉及高延迟的操作,如浮点指令或具有局部较低访问的存储指令。

考虑下面简单的C循环,它可以在一个字内反转位的顺序。在这个代码中,“in”和“out”都被声明为无符号整数:

当ARM GCC 4.8.2-19使用最大优化(使用“-O3”开关)来编译时,并且强制编译器生成ARM模式代码,而不是THUMB模式代码(通过使用“-mcpu = cortex-a15 –marm”开关),编译器生成如下的汇编代码,这里的“in”变量分配给寄存器r0:

编译器生成的汇编代码看起来是合理的,但它可能会利用C语言无法描述的指令集特性来减少循环体中的指令数。

具体来说,当使用移位操作时,无论是作为独立指令还是作为灵活的第二个操作数,最后移出位均被存储在进位标志。同时,向右旋转和扩展(RRX)操作允许将进位标志转移到一个寄存器上。在使用相反的移位操作时,这允许使用进位标志在原始和反向寄存器之间传输。一个额外的好处是,在所有的位已被移出源寄存器时,程序可以终止循环,消除自增变量i需要的指令。这种方法的代码和目的如下。

在这个版本中,循环体由两个指令减少。假设需要与上一版本相同的指令,将加速6/4 = 1.5倍,这使得代码的执行速度快了50%。

这种假设是不现实的,因为改变指令序列可能也改变了其他一些性能因素。其结果是,实际性能改善可能大于或小于50%。具体而言,修改代码也可能有改变:

每个指令所需的时钟周期的平均数(指令平均时钟周期数,简写为CPI)。

指令高速缓存失效率。

或者如果循环包含了加载和存储指令,数据缓存失效率的变化来自潜在地改变存储访问模式。

因此,静态指令代码不一定转化为相对性能影响。为了准确地捕捉代码变化的影响,程序员必须通过性能分析来检测程序的运行时行为。

性能分析的目的是在一个实际的处理器或者一个周期精确的模拟器上收集程序运行时的信息。周期精确的模拟器能够将与性能相关的事件串成线或用代码形式呈现,但是这会变慢,并会限制程序和数据集的可测试范围。使用一个实际的处理器速度要快得多,但只能使用性能计数器以汇总方式收集信息。

本书使用性能计数器进行性能分析。性能计数器是一个低级别的架构特征,如果没有一个或多个抽象层的帮助下,通常很难使用。Linux提供了一个系统级的抽象概念,本章将介绍如何在上面构建一个用户级的抽象。


喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书频道活动讨论群:365934973

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

PHP5与MySQL5 Web开发技术详解

本书是目前中文版本第一个真正介绍PHP 5及MySQL 5新增语法与功能的权威宝典! 本书本着精、全、要三宗旨,从理论中延伸,从实践中深入,详...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊