微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 高效的C编程之:寄存器分配

高效的C编程之:寄存器分配

时间:08-30 来源:3721RD 点击:

total2+= *i;

}

编译后生成:

add:

0000807C E3A01000 MOV r1,#0

>>> POINTALIAS\#3 int total1=0,total2=0;

00008080 E3A02000 MOV r2,#0

>>> POINTALIAS\#5 total1+= *i;

00008084 E5903000 LDR r3,[r0,#0]

00008088 E0831001 ADD r1,r3,r1

>>> POINTALIAS\#6 total2+= *i;

0000808C E5903000 LDR r3,[r0,#0]

00008090 E0832002 ADD r2,r3,r2

>>> POINTALIAS\#8 }

00008094 E12FFF1E BX r14

>>> POINTALIAS\#11 {

注意程序中i的值被装载了两次。因为编译器不能确定指针*i是否有别名存在,这就使得编译器不得不增加一条额外的Load指令。

另一个问题,当在函数中要获得局部变量地址时,这个变量就被一个指针所对应,就可能与其他指针产生别名。为了防止别名发生,在每次对变量操作时,编译器就会从堆栈中重新读入数据。考虑下面的例子程序,分析其产生的编译结果。

void f(int *a);

int g(int a);

int test1(int i)

{ f(&i);

/* now use ’i’ extensively */

i += g(i);

i += g(i);

return i;

}

编译结果如下所示。

test1

STMDB sp!,{a1,lr}

MOV a1,sp

BL f

LDR a1,[sp,#0]

BL g

LDR a2,[sp,#0]

ADD a1,a1,a2

STR a1,[sp,#0]

BL g

LDR a2,[sp,#0]

ADD a1,a1,a2

ADD sp,sp,#4

LDMIA sp!,{pc}

从上面代码的编译结果可以看出,对每一次i操作,编译器都将会从堆栈中读出其值。这是因为,一旦在函数中出现对i的取值操作,编译器就会担心别名问题。为了避免这种情况,尽量不要在程序中使用局部变量地址。如果必须这么做,那么可以在使用之前先把局部变量的值复制到另外一个局部变量中。下面的程序是对test1函数的优化。

int test2(int i)

{

int dummy = i;

f(&dummy);

i = dummy;

/* now use ’i’ extensively */

i += g(i);

i += g(i);

return i;

}

编译后的结果如下。

test2

STMDB sp!,{v1,lr}

STR a1,[sp,#-4]!

MOV a1,sp

BL f

LDR v1,[sp,#0]

MOV a1,v1

BL g

ADD v1,a1,v1

MOV a1,v1

BL g

ADD a1,a1,v1

ADD sp,sp,#4

LDMIA sp!,{v1,pc}

从编译结果可以看出,修改后的代码只使用了2次内存访问,而test1为4次内存访问。

总上所述,为了在程序中避免指针别名,应该做到:

· 避免使用局部变量地址;

· 如果程序中出现多次对同一指针的访问,应先将其值取出并保存到临时变量中。

2.全局变量

通常情况下,编译器不会为全局变量分配寄存器。这样在程序中使用全局变量,很可能带来内存访问上的开销。所有尽量避免在循环体内使用全局变量,以减少对内存的访问次数。

如果在一段程序体内大量使用了同一个全局变量,建议在使用前先将其拷贝到一个局部的临时变量中,当完成对它的全部操作后,再将其写回到内存。

比较下面两个完成同样功能的函数,分析全局变量的操作对程序性能的影响。

int f(void);

int g(void);

int errs;

void test1(void)

{

errs += f();

errs += g();

}

void test2(void)

{

int localerrs = errs;

localerrs += f();

localerrs += g();

errs = localerrs;

}

编译结果如下。

test1

STMDB sp!,{v1,lr}

BL f

LDR v1,[pc, #L00002c-.-8]

LDR a2,[v1,#0]

ADD a1,a1,a2

STR a1,[v1,#0]

BL g

LDR a2,[v1,#0]

ADD a1,a1,a2

STR a1,[v1,#0]

LDMIA sp!,{v1,pc}

L00002c

DCD |x$dataseg|

test2

STMDB sp!,{v1,v2,lr}

LDR v1,[pc, #L00002c-.-8]

LDR v2,[v1,#0]

BL f

ADD v2,a1,v2

BL g

ADD a1,a1,v2

STR a1,[v1,#0]

LDMIA sp!,{v1,v2,pc}

从编译的结果中可以看出,test1中每次对全局变量

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top