关于ARM的C语言优化

关于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 个周期,可展开循环体(重复写几遍循环体代码),以免循环体代码还不如循环本身执行周期长;当然,这样做也增加了代码长度。
 

你可能感兴趣的:(关于ARM的C语言优化)