高效的C编程之:C编译器及其优化(中)

来源:本站
导读:目前正在解读《高效的C编程之:C编译器及其优化(中)》的相关信息,《高效的C编程之:C编译器及其优化(中)》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《高效的C编程之:C编译器及其优化(中)》的详细说明。
简介:本章将帮助读者在ARM处理器上编写高效的C代码。本章涉及的一些技术不仅适用于ARM处理器,也适用于其他RISC处理器。本章首先从ARM编译器及其优化入手,讲解C编译器在优化代码时所碰到的一些问题。(EEFOCUS)

2.冗余代码的清除

下面例子显示了一段急待优化的代码。

intdummy()

{

inta=10,b=20;

intc;

c=a+b;

return0;

}

当使用arm–c–O0进行编译时,产生的汇编码如下所示。

dummy:

0000807CE3A0100AMOV r1,#0xa

>>>REDUNDANT#3inta=10,b=20;

00008080E3A02014MOV r2,#0x14

>>>REDUNDANT#5c=a+b;

00008084E0813002ADD r3,r1,r2

>>>REDUNDANT#6return0;

00008088E3A00000MOV r0,#0

>>>REDUNDANT#7}

0000808CE12FFF1EBX r14

从上面的汇编输出可以看到,编译器并没有对程序中的冗余变量做任何工作。但上面这段代码在编译时,编译器会给出警告,警告信息如下所示。

Warning:#550-D:variable"c"wassetbutneverused

Redundant.cline4intc;

但如果将编译器的优化级别提高,如使用arm–c–O1命令,则编译器输出的汇编代码如下所示。

dummy:

0000807CE3A00000MOVr0,#0

>>>REDUNDANT#7}

00008080E12FFF1EBXr14

从上面的例子看出,当优化级别提高到-O1时,程序中的冗余变量就会被清除。

3.指令重排

当指定编译器对程序代码进行优化时,编译器会对程序中排列不合理的汇编指令序列进行重排(只有在-O1及其以上的优化级别中才有),重排的目的是为了减少指令互锁(interload)。所谓互锁就是指如果一条指令需要前一条指令的执行结果,而这时结果还没有出来,那么处理器就会等待。这被称为流水线冒险(pipelinehazard),也被称为流水线互锁。

下面例子显示了对同一程序使用代码重排和不使用代码重排所产生的汇编码的区别。÷

程序的源代码如下所示。

intf(int*p,intx)

{return*p+x*3;}

使用-O0选项对代码进行编译(无代码重排),产生的结果如下所示。

ADDr1,r1,r1,LSL#1

LDRr0,[r0,#0]

ADDr0,r0,r1 ;ARM9上产生互锁

MOVpc,lr

使用-O1选项对代码进行编译(存在代码重排),产生的结果如下所示。

ADDr1,r1,r1,LSL#1

ADDr0,r0,r1

MOVpc,lr

指令重排发生在寄存器定位和代码产生阶段。代码重排只对ARM9及其以后的处理器版本产生作用。当使用代码重排时,代码的执行速度平均提供4%。可以使用-zpno_optimize_

scheduling编译选项关闭代码重排。

4.内嵌函数

通常情况下,如果不指定编译选项,编译器会将一些代码量小且调用次数少的函数内嵌进调用函数中。如果某段子程序在其他模块中没有被调用,请使用Static关键字将其标识。

编译选项的--autoinline和--no_autoinline可以作为内嵌函数的使能开关。--no_autoinline选项为-O0和-O1选项的默认选项,但如果指定-O2或-O3的优化选项,编译器将默认使用--autoinline选项。

有关内嵌函数的详细信息,请参见本书内嵌函数一节。

提醒:《高效的C编程之:C编译器及其优化(中)》最后刷新时间 2024-03-14 01:07:26,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《高效的C编程之:C编译器及其优化(中)》该内容的真实性请自行鉴别。