本文摘要:程序优化是指软件编程完结后,利用软件开发工具对程序展开调整和改良,让程序充分利用资源,提升运营效率,削减代码尺寸的过程。
程序优化是指软件编程完结后,利用软件开发工具对程序展开调整和改良,让程序充分利用资源,提升运营效率,削减代码尺寸的过程。按照优化的侧重点有所不同,程序优化可分成运营速度优化和代码尺寸优化。
运营速度优化是所指在充份掌控软硬件特性的基础上,通过应用程序结构调整等手段来减少已完成登录任务所须要继续执行的指令数。在同一个处理器上,经过速度优化的程序比予以优化的程序在已完成登录任务时所须要的时间更加较短,即前者比后者具备更高的运营效率。
代码尺寸优化是指,采取措施使应用程序在需要准确已完成所须要功能的前提下,尽可能减少程序的代码量。 然而在实际的程序设计过程中,程序优化的两个目标(运营速度和代码大小)一般来说是互相矛盾的。为了提升程序运行效率,往往要以壮烈牺牲存储空间、减少代码量为代价,例如程序设计中常常用于的以排序替换计算出来、循环展开等方法就更容易造成程序代码量减少。而为了增加程序代码量、传输存储器空间,有可能又要以减少程序运行效率为代价。
因此,在对程序实施优化之前,应先根据实际市场需求确认适当的策略。在处理器资源紧绷的情况下,不应侧重考虑到运营速度优化;而在存储器资源用于有限的情况下,则不应优先考虑到代码尺寸的优化。 1程序运行速度优化 程序运行速度优化的方法可分成以下几大类。
1.1标准化的优化方法 (1)增大运算强度 利用左/右移位操作者替换乘/除2运算:一般来说必须除以或除以2的幂次方都可以通过左移或右移n位来已完成。实质上除以任何一个整数都可以用移位和乘法来替换乘法。arm7中乘法和移位可以通过一条指令来已完成,且继续执行时间多于乘法指令。
例如:i=i5可以用i=(i《《2)+i来替换。 利用乘法替换乘方运算:arm7核中内设有328乘法器,因此可以通过乘法运算来替换乘方运算以节约乘方函数调用的支出。例如:i=pow(i,3.0)能用i=iii来替换。
利用与运算替换求余运算:有时可以通过用与(AND)指令替换求余操作者(%)来提高效率。例如:i=i%8可以用i=i0x07来替换。
(2)优化循环中止条件 在一个循环结构中,循环的中止条件将严重影响着循环的效率,再行再加arm指令的条件继续执行特性,所以在书写循环的中止条件时应尽可能用于count-down-to-zero结构。这样编译器可以用一条BNE(若非零则函数调用)指令替换CMP(较为)和BLE(若大于则函数调用)两条指令,既增大代码尺寸,又减缓了运营速度。 (3)用于inline函数 armC反对inline关键字,如果一个函数被设计成一个inline函数,那么在调用它的地方将不会用函数体来替代函数调用语句,这样将不会完全省却函数调用的支出。
用于inline的仅次于缺点是函数在被频密调用时,代码量将减小。 1.2处理器涉及的优化方法 (1)维持流水线通畅 从前面的讲解由此可知,流水线延后或切断不会对处理器的性能导致影响,因此应当尽可能维持流水线通畅。流水线延后难以避免,但可以利用延后周期展开其它操作者。
LOAD/STORE指令中的自动索引(auto-indexing)功能就是为利用流水线延后周期而设计的。当流水线正处于延后周期时,处理器的继续执行单元被闲置,算术逻辑单元(ALU)和桶形移位器却有可能正处于空闲状态,此时可以利用它们来已完成往基址寄存器上加一个偏移量的操作者, 可供后面的指令用于。例如:指令LDRR1,[R2],#4已完成R1=*R2及R2+=4两个操作者,是后索引(post-indexing)的例子;而指令LDRR1,[R2,#4]!已完成R1=*(R2+4)和R2+=4两个操作者,是前索引(pre-indexing)的例子。
流水线切断的情况可通过循环报废等方法加以提高。一个循环可以考虑到报废以增大函数调用指令在循环指令中所占到的比重,进而提升代码效率。
下面以一个内存拷贝函数加以解释。 voidmemcopy(char*to,char*from,unsignedintnbytes) { while(nbytes--) *to++=*from++; } 为非常简单起见,这里假设nbytes为16的倍数(省略对余数的处置)。
上面的函数每处置一个字节就要展开一次辨别和函数调用,对其中的循环体可不作如下报废: voidmemcopy(char*to,char*from,unsignedintnbytes) { while(nbytes){ *to++=*from++; *to++=*from++; *to++=*from++; *to++=*from++; nbytes-=4; } } 这样一来,循环体中的指令数减少了,循环次数却增加了。函数调用指令带给的负面影响以求巩固。
利用arm7处理器32位字长的特性,上述代码可更进一步不作如下调整: voidmemcopy(char*to,char*from,unsignedintnbytes) { int*p_to=(int*)to; int*p_from=(int*)from; while(nbytes){ *p_to++=*p_from++; *p_to++=*p_from++; *p_to++=*p_from++; *p_to++=*p_from++; nbytes-=16; } } 经过优化后,一次循环可以处置16个字节。函数调用指令带给的影响更进一步获得弱化。不过可以显现出,调整后的代码在代码量方面有所增加。
(2)用于寄存器变量 CPU对寄存器的读取要核对内存的读取更快,因此为变量分配一个寄存器,将有助代码的优化和运营效率的提升。整型、指针、浮点等类型的变量都可以分配寄存器;一个结构的部分或者全部也可以分配寄存器。给循环体中必须频密采访的变量分配寄存器也能在一定程度上提升程序效率。
本文来源:澳门体育app官方下载-www.orzba.com