资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,嵌入式系统程序设计,大连理工大学软件学院,嵌入式系统工程系,赖晓晨,ARM C程序设计优化,编译器的特性,数据类型对程序效率的影响,循环方式对程序效率的影响,指针对程序效率的影响,边界对齐对程序的影响,一、编译器的特性,void,setzero,(char*,p,int,n,),for(;,n,0;,n,-),*,p,=0;,p,+;,清除从,字符型,指针,p,开始的,n,个字节空间,编译器的特性(续),void,setzero,(char*,p,int,n,),for(;,n,0;,n,-),*,p,=0;,p,+;,问题:,编译器不知道,n,是否为0。,编译器不知道,p,是否4字节对齐。,编译器不知道,n,是否为4的倍数,。,结论:,编译器是保守的:,必须假定,n,的所有可能值,。,必须假定,p,所有可能的边界值,。,编写高效C代码的要求,了解哪些方面编译器是保守的,了解编译器对应的处理器体系结构,二、数据类型对程序效率的影响,unsigned char,i;,for(i=0;i,100,;i+),i声明为,unsigned,char的优点?,无符号字符变量表示,的范围超过了,100,,可以完成题目要求。,char更节省寄存器和内存空间。,函数参数类型,总体思想:尽量采用int、long类型,。,有符号数和无符号数,如果程序中只有加、减、乘法,那么有符号数和无符号数的执行效率没有区别。,如果有除法,那么需要额外的步骤。,有符号数和无符号数,(续),有符号除法,在ARM C中,如果x是负数,那么除2操作不是一个右移操作。例如-3/2=-1。但是在ARM机器中:,-3,-2,-1,直接右移,加1右移,结论:,使用无符号数除法效率更高,。,对于存放在寄存器中的变量,尽量采用整型。,尽可能使用无符号数进行运算,。,函数参数和返回值尽量采用整型数据。,总结,三、循环方式对程序效率的影响,循环是代码优化的重点,C程序主要使用for和while进行循环,固定次数的循环,什么是ARM上编写for循环最高效的方法?,固定次数的循环,(续),int,i;,for(i=0;i0,;i,-,),上面代码要实现转移需要两条指令,首先把某寄存器的内容和100比较,其次条件符合时转移。相同功能的代码如果写作下面形式,则可用“BNE”一条指令实现比较以及转移两个功能。,至少一次循环,对于,“for(;n0;n-)”,如果能确保第一次循环之前n恒大于0,此时取消第一次n大于0的判断,是不会影响程序的逻辑,而且显然程序执行效率可以提高,用dowhile循环可以达到这一目的,循环展开,循环开销重复100次,假设每次循环开销占用4个时钟周期,循环体中的加法占用1个时钟周期,那么有效程序仅占CPU执行时间的20%,其余80%都是服务性开销,效率为1/5。,int,i,t=0,;,for(i=,10,0;i,0,;i,-,),t+;,循环展开(续),int,i,t=0,;,for(i=,5,0;i,0,;i,-,),t+;,t+;,每次循环开销4个时钟周期不变,但是有效程序占用2个时钟周期,也即效率提高到1/3。,循环展开(续),问题:,循环展开到什么程度?全部展开是否最优?要意识到循环展开是有代价的:,增加程序的长度。,循环体内代码越多,就越有可能造成cache失效,所以在任何程度上展开循环要具体问题具体分析,在执行时间和代码量间找到一个最佳平衡点。,总结:,循环计数递减。,如确定循环次数大于1,那么用dowile。,对于小循环体,可以循环展开。,四、指针对程序效率的影响,别名,当两个指针指向同一个对象时,这两个指针被称作该对象的别名。,编译器的特点:,不知道是否是别名,编译器是悲观的,指针对程序效率的影响(续),void t,hrowtobag,(int*,mybag,int*,yourbag,int,*s,tone,),*,mybag,+=*s,tone,;,/语句1,*,yourbag,+=*s,tone,;,/语句2,站在编译器的角度思考一下有无问题?,指针对程序效率的影响(续),上面代码的语句1被GCC编译时,会出现诸如“LDR ri,r2,#0”之类汇编指令,表示首先要从stone指向的地址读出一个数据,以便来把它加到mybag指向指明的地址处。此处r2代表stone,因为它是函数的第三个参数,轮到r2来承载它。令人惊奇的是,编译语句2时,仍然包含一条“LDR ri,r2,#0”语句,stone的值不是已经由语句1得到了吗?,为什么还要这一条语句?,指针对程序效率的影响(续),讨论:编译器不会自动识别指针指向的对象,不知道是否是别名,悲观、保守,思考:采用什么办法可以避免读两次内存?,五、边界对齐对程序的影响,边界对齐,问题,_packed关键字,边界对齐,问题,对齐问题对结构体也有影响。在结构体中定义若干变量如果长短相间,由于对齐问题,势必浪费一些空间。例如一个整形变量和一个字符变量放在一起,总共占用8个字节空间,但是其中保存有效数据的只有5个字节。所以可以采用这种策略:,在结构体的最前面定义的所有的字符型变量,中间定义所有的短整型变量,最后定义所有的整形变量,,可以把浪费的空间减到最小。,_packed关键字,有的C编译器支持,_packed,关键字,它可以突破边界对齐的限制,在任意类型的变量按照任意顺序定义的情况下,都能够紧凑的安排存储空间,此时的代价是牺牲程序的运行效率,_packed关键字,(续),代码完成从任意地址p处读取一个整型变量,且不要求此地址是4的整数倍,返回值为此地址起始的4字节数据。,int,fetchint(,_packed,int*p),return*p;,_packed关键字,(续),上图是上述代码的实例,数据按照小端存储,读取一个没有对齐的整型数据。,_packed关键字,(续),地址不对齐时,即使是非常简单的读取一个整型数据,也比较复杂。,_packed,节约了空间,但是损失了运行效率。在硬件资源已经非常丰富的今天,空间限制已经不是主要矛盾,程序效率往往更受人关注。,树立质量法制观念、提高全员质量意识。,11月-24,11月-24,Thursday,November 14,2024,人生得意须尽欢,莫使金樽空对月。,13:05:11,13:05:11,13:05,11/14/2024 1:05:11 PM,安全象只弓,不拉它就松,要想保安全,常把弓弦绷。,11月-24,13:05:11,13:05,Nov-24,14-Nov-24,加强交通建设管理,确保工程建设质量。,13:05:11,13:05:11,13:05,Thursday,November 14,2024,安全在于心细,事故出在麻痹。,11月-24,11月-24,13:05:11,13:05:11,November 14,2024,踏实肯干,努力奋斗。,2024年11月14日,1:05 下午,11月-24,11月-24,追求至善凭技术开拓市场,凭管理增创效益,凭服务树立形象。,14 十一月 2024,1:05:11 下午,13:05:11,11月-24,严格把控质量关,让生产更加有保障。,十一月 24,1:05 下午,11月-24,13:05,November 14,2024,作业标准记得牢,驾轻就熟除烦恼。,2024/11/14 13:05:11,13:05:11,14 November 2024,好的事情马上就会到来,一切都是最好的安排。,1:05:11 下午,1:05 下午,13:05:11,11月-24,一马当先,全员举绩,梅开二度,业绩保底。,11月-24,11月-24,13:05,13:05:11,13:05:11,Nov-24,牢记安全之责,善谋安全之策,力务安全之实。,2024/11/14 13:05:11,Thursday,November 14,2024,相信相信得力量。,11月-24,2024/11/14 13:05:11,11月-24,谢谢大家!,
展开阅读全文