嵌入式程序代码优化 A

  • 格式:ppt
  • 大小:165.00 KB
  • 文档页数:54

下载文档原格式

  / 54
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
嵌入式系统
嵌入式程序代码优化
提纲
代码优化概述 提高代码效率 减少代码尺寸 有效使用内存 降低代码能耗
提纲
代码优化概述 提高代码效率 减少代码尺寸 有效使用内存 降低代码能耗
嵌入式程序代码优化概述(1)
程序优化是指在不改变程序功能的前提下, 对程序代码进行调整和改进,让计算机资 源被程序充分利用
其它代码优化技术(3)
把频繁使用的指针型参数拷贝到本地变量
避免在函数中频繁使用指针型参数指向的值 主要原因是如果一直使用指针的话,数据不能
被存放在寄存器中,代码效率较低,而且明显 地占用了内存带宽 比较好的做法是,在函数开始处,就把指针指 向的数据保存到本地变量,在函数结束前再拷 贝回指针
switch (ReceiveMessage() {
case Msg1; 。。。。。。
case Msg2; 。。。。。
case Msg3; 。。。。。
}
/*准备工作*/
int handleMsg1(void);
int handleMsg2(void);
int handleMsg3(void); /*创建一个函数指针数组*/ int (*MsgFunction [])()={handleMsg1, handleMsg2, handleMsg3}; /*用下面这行更有效的代码来替换 switch语句*/
运算优化(4)
用移位实现乘除法/除法运算
a=a*4; b=a/4; c=a/9;
a=a<<2; b=a>>2; c=a>>3 + a;
运算优化(5)
避免不必要的整数除法
int i, j, k, m; m = i / j / k;
if ( (x / y) > z)
int i, j, k, m; m = i / (j * k);
short shortinc(short a) char charinc(char a)
{
{
int b=a+1;
int b=a+1;
return b;
return b;
}
}
ADD a1,a1,#1 MOV pc,lr
ADD a1,a1,#1 MOV a1,a1,LSL #16 MOV a1,a1,ASR #16 MOV pc,lr
嵌入式程序代码优化概述(3)
有效使用内存是指在程序中采用正确、可靠地 方式使用内存,最大限度提高嵌入式系统容量 较小的内存的利用效率,避免内存被浪费或泄 漏情况的发生,提高资源利用率的同时,同时 提高可靠性
降低代码能耗是从宏观角度出发,通过寻找和 分析程序的热点,采用调整程序业务逻辑和程 序运行方式或提高热点代码的运行效率等方法, 提高硬件资源的利用效率,从而降低运行代码 所需要消耗的能耗
i++; //用户程序 }
unsigned int i; i=1000; do {
i--; //用户程序 } while (i>0);
循环结构优化(5)
循环中条件语句
for( i=0; i<N; i++) {
if(expression) {
foo0( i ); } else {
foo1( i ); } } 注:foo0( i )和foo1(i)不能改变 expression的值。
处理器在执行LDM/STM 指令的时候还是将 它拆分成多条单独的LDR/STR 指令来执行
合理安排变量顺序(1)
ARM处理器要求程序中的32位/16位变量必 须按字/半字对齐,如果变量顺序安排不合 理, 有可能会造成存储空间的浪费
合理安排变量顺序(2)
结构体安排
合理安排变量顺序(3)
在结构体定义时,变量顺序的安排原则应 该是先安排位宽长的变量,然后再安排位 宽短的变量,可以减少存储空间的浪费
利用硬件特性
为了提高程序的运行效率,要充分利用硬 件特性来减小其运行开销,例如减少中断 次数、利用DMA传输方式等
一些硬件厂商针对多媒体处理、图形处理 和数值运算的一些典型操作和算法进行了 手工优化,可以很好地发挥硬件的计算潜 能,达到较高的执行效率
其它代码优化技术(1)
switch语句中根据发生频率来进行case排序。当 switch用比较链的方式转化时,编译器会产生ifelse-if的嵌套代码,并按照顺序进行比较,匹配 时就跳转到满足条件的语句执行
由于当编译器分配给本地变量空间时,顺 序与它们在源代码中声明的顺序一样
循环结构优化(2)
充分分解小的循环
for (i = 0; i < 4; i ++) {
r[i] = 0; for (j = 0; j < 4; j ++) {
r[i] += M[j][i]*V[j]; }
}
r[0] = M[0][0]*V[0] + M[1][0]*V[1] + M[2][0]*V[2] + M[3][0]*V[3];
可以对case的值依照发生的可能性进行排序,把 最有可能的放在第一位,这样可以提高性能
将大的switch语句转为嵌套switch语句 在case中推荐使用小的连续的整数,在这种情况
下,所有的编译器都可以把switch 转化成跳转表。
int days_in_month, short_months, normal_months, long_months; ……
提纲
代码优化概述 提高代码效率 减少代码尺寸 有效使用内存 降低代码能耗
提高代码效率
C语言数据类型优化 循环结构优化 运算优化 内联函数和内联汇编优化 利用硬件特性 其它代码优化技术
C语言数据类型优化(1)
ARM指令集支持有符号/无符号的8位、16位 和32位整型及浮点型变量
break; }
int days_in_month, short_months, normal_months, long_months; ……
switch (days_in_month)
{
case 31: long_months ++; break;
case 30: normal_months ++; break;
case 28:
case 29: short_months ++; break;
default:
cout << "month has fewer than 28 or more than 31 days" << endl;
break; }
enum MsgType{Msg1, Msg2, Msg3}
else
{
return i * factorial(i - 1); return factorial_table[i];
}
}
运算优化(2)
求余运算
b = a%8;
b = a&7;
运算优化(3)
n次方运算
b = pow(a, 2.0); c = pow(a, 3.0);
b=a*a; c=a*a*a;
恰当的使用变量的类型,不仅可以节省代 码,并且可以提高代码运行效率
应该尽可能地避免使用char、short型的局 部变量,因为操作8位/16位局部变量往往 比操作32位变量需要更多指令
返回值类型原理类似
C语言数据类型优化(2)
int wordinc(int a) {
iwenku.baidu.comt b=a+1; return b; }
if ( x > (y * z))
运算优化(8)
提取公共的子表达式
a = b / c * d; b = b / c * g;
t = b / c; a = t * d; b = t * g;
内联函数和内联汇编优化(1)
内联函数
inline函数请求编译器用函数内部的代码替换 所有对于指出的函数的调用,省去了调用指令 需要的执行时间;省去了传递变元和传递过程 需要的时间。缺点是程序长度变大
循环结构优化(3)
提取公共部分
对于一些不需要循环变量参加运算的任务可以把 它们放到循环外面,这里的任务包括表达式、函 数的调用、指针运算、数组访问等,应该将没有 必要执行多次的操作全部集合在一起,放到一个 init的初始化程序中进行
循环结构优化(4)
while循环和do…while循环
unsigned int i; i=0; while (i<1000) {
结合嵌入式系统硬件资源受限、高可靠性 要求等的特点,代码优化的侧重目标
提高代码效率 减少代码尺寸 有效使用内存 降低代码能耗
嵌入式程序代码优化概述(2)
提高代码效率是指在充分掌握软硬件特性 的基础上,通过应用程序结构调整等手段 来降低完成指定任务所需执行的执行时间
减少代码尺寸是指采取措施使应用程序在 能够正确完成指定任务的前提下,尽可能 减少程序代码所占用存储空间的尺寸
这种优化方法在inline函数被频繁调用且只包 含几行代码时,效果是最好的。
内联函数和内联汇编优化(2)
char string1[1024],string2[1024]; int I; for (I =0 I<1024;I++)
*(string2 + I) = *(string1 + I)
__asm {
for (;;); jmp foo+23h
运算优化(1)
查表计算
long factorial(int i)
static long factorial_table[] =
{
{1, 1, 2, 6, 24, 120,
if (i == 0)
720 /* etc */ };
return 1;
long factorial(int i)
ADD a1,a1,#1 AND a1,a1,#&ff MOV pc,lr
循环结构优化(1)
循环展开优化
unsigned int i; for(i=N;i!=0;i--) {
foo()… }
unsigned int i; for(i=N>>2;i!=0;i--) {
foo()… foo()… foo()… foo()… } for(i=N&3;i!=0;i--) { foo()… }
if(expression) {
for(i=0; i<N; i++) {
foo0( i ); } } else { for(i=0; i<N; i++) {
foo1( i ); } }
循环结构优化(6)
无限循环的选择
while (1); mov eax,1 test eax,eax je foo+23h jmp foo+18h
switch (days_in_month)
{
case 28:
case 29: short_months ++; break;
case 30: normal_months ++; break;
case 31: long_months ++; break;
default:
cout << "month has fewer than 28 or more than 31 days" << endl;
r[1] = M[0][1]*V[0] + M[1][1]*V[1] + M[2][1]*V[2] + M[3][1]*V[3];
r[2] = M[0][2]*V[0] + M[1][2]*V[1] + M[2][2]*V[2] + M[3][2]*V[3];
r[3] = M[0][3]*V[0] + M[1][3]*V[1] + M[2][3]*V[2] + M[3][3]*v[3];
提纲
代码优化概述 提高代码效率 减少代码尺寸 有效使用内存 降低代码能耗
减少代码尺寸
使用多寄存器操作指令 合理安排变量顺序 使用Thumb 指令
使用多寄存器操作指令
ARM 指令集中的多寄存器操作指令LDM/STM 可以加载/ 存储多个寄存器,这在保存/ 恢复寄存器组的状态及进行大块数据复制 时非常有效
status=MsgFunction[ReceiveMessage(
)]();
其它代码优化技术(2)
使用嵌套的if结构
在if结构中如果要判断的并列条件较多,最好 将它们拆分成多个if结构,然后嵌套在一起, 这样可以避免无谓的判断
与switch的case顺序优化的原理一样,出现概 率高的分支应放到靠前的位置
MOV R0,string1 MOV R1,string2 MOV R2,#0 loop: LDMIA R0!, [R3-R11] STMIA R1!, [R3-R11] ADD R2,R2,#8 CMP R2, #400 BNE loop }
内联函数和内联汇编优化(3)
自定义系统调用或底层操作等无法用简单 的语句实现的,可用内联式汇编实现