关于ARM的C语言优化
ARM是32位总线,以32位访问数据的速度较快。局部变量和其他常用的变量要尽量利用32位的int类型,组织结构体时,也要注意元素的位置(小前大后),以节省空间。
对于编译器,armcc遵从ATPCS的要求,第一到第四个参数依次通过r0~r3传递,其他参数通过堆栈传递,返回值用r0传递,因此,为了把大部分操作放在寄存器中完成,参数最好不多与4个。另外,可用的通用寄存器有12个,所以尽量将局部变量控制在12个之内,效率上会得到提升。同时,由于编译器比较保守,指针别名会引起多余的读操作,所以尽量少用。
※ 在默认的情况下,armcc是全部优化功能有效的,而GNU编译器的默认状态下优化都是关闭的。ARM C编译器中定义的char类型是8位无符号的,有别于一般流行的编译器默认的char是8位有符号的。
char 无符号8位字节数据
short 有符号16位半字节数据
int 有符号32位字数据
long 有符号32位字数据
long long 有符号64位双字数据
※ 存放在寄存器中的局部变量应尽可能使用32位的数据类型(int或long)。就算处理8位或者16位的数值,也应避免使用char和short。
※ 函数参数和返回值应尽量使用int类型,即使传递一个8位数据,函数参数和返回值使用32位类型会更有效。
※ 建立一个新的局部变量来保存包含存储器访问的表达式,这样可以保证只对存储器访问一次,例如int a=data[n];b+=a;c+=a; 比b+=data[n];c+=data[n];要好。
※ 避免使用局部变量的地址,否则访问这个变量的效率较低。
※ 存放在存储器中的全局变量,尽量使用小的数据类型(char和short)以节省空间。
※ 用指针代替数组操作,能用指针递增寻址就不用数组下标递增寻址,比如用a=*(data++)比a=data[i++]好;
※ 使用减数到零的循环体,以节省指令和寄存器的使用。使用无符号的循环计数值,并用条件 i != 0中止,而不是i>0,这样循环的开销只有2条指令 ;如果循环体至少执行一次,应优先选用do-while。
※ 尽量限制函数参数,不要超过四个,也可以把相关的参数组织在结构体传递。ARM中的函数前4个整型参数通过寄存器r0、r1、r2、r3来传递,随后的整型参数通过堆栈(full desceding stack)来传递。
※ 尽量限制函数内部循环所用局部变量的数目,最多不超过12个,以便编译器能把变量分配到寄存器。
※ 若循环体过于简单,比如少于4个周期,可展开循环体(重复写几遍循环体代码),以免循环体代码还不如循环本身执行周期长;当然,这样做也增加了代码长度。
3879

被折叠的 条评论
为什么被折叠?



