软件优化是一项系统工程。总体而言,整个优化框架可以分为两个部分:设计优化和代码优化。
1,设计优化
设计优化包括了软件体系结构的优化,数据结构的优化,算法的优化。
1.1 软件体系结构的优化
软件优化首先要对整个软件体系结构有个清晰的了解。在认识了整个软件的目标功能后,围绕这个目标,软件的模块划分,软件的运行流程都要一清二楚。整个软件的“数据流”和“控制流”都要能在头脑中清晰的呈现出来。各个模块的接口和各个模块的数据结构间的关系,都要有清晰的认识。在这个基础上,才能对各个模块做数据结构的优化和算法的优化。
1.2 数据结构的优化
数据结构的设计是个大学问。基本上,数据结构是为算法服务的,所以要根据算法来确定数据结构。但也有几个我认为比较通用的原则。
第一, 除非算法有特殊的需要,否则尽量用紧凑性好的数据结构,如数组。
第二, 根据空间局部性原理,尽量紧凑经常访问的数据,合理选择数组结构和结构数组。
第三, 如果数组比较大,其元素的尺寸应尽可能小,如可以用char就不要用short。除此以外,不要吝惜内存,尽量用int作为数据类型。
第四, 如果CPU具有SIMD指令,则第三点要重新考虑,根据算法需要,合理安排
数组元素的尺寸。
1.3 算法的优化
算法的优化可以分为两种:算法设计的优化和算法实现的优化。
1.3.1 算法设计的优化
算法设计的优化是指对求解的问题提出更具效率的求解思路。好的算法设计对软件性能具有决定性影响。例如Video Encoder中motion vector的搜索算法有很多,选择合适的算法是很重要的。同时,算法设计也是最有挑战的,需要许多的实验并根据应用需要。
1.3.2 算法实现的优化
相对于算法设计的优化,算法实现的优化就简单一些了。基本上,算法实现的优化有两种思路。
第一, 避免计算。最好的优化就是“不计算”,仔细观察算法的实现,如果发现某些部分的计算结果在某些条件下是“还原”的,那就是说这个部分是做了“无用功“了。那么就可以尝试通过一些控制条件去避免计算。如Video decoer的IDCT,统计一下各个分块的值分布,就可以改进算法实现,避免一些块的计算。提高效率。
第二, 重用计算。如果计算不可避免,就可以观察是否可以重用已有计算。这其实也是一种“避免计算”,只不过前提是调整算法实现,使得一些计算可以被重用。
2,代码优化
如果说设计优化是全局性的,是“内行”做的事情,那么代码优化就是局部性的,是“外行“也可以做的事。如一个有代码优化经验的Audio Codec工程师虽然没有Video Codec的经验,但是同样可以对Video Codec的代码进行优化。因为代码优化依据的原理通常是可以适用于各个领域和平台的。如loop unroll通常是有效的。代码优化因为可以是“只见树木不见森林”,所以它的影响不是全局性的。套用一个代码优化专家的话说,代码优化通常可以使得一个慢的程序变的快一些。我的理解是,如果脱离了设计优化,慢的程序做再多的代码优化也不过是一个快了一些的“慢程序”。
同理,好的代码优化能使好的设计如虎添翼。因为通常好的设计,或者说遵循局部性原理的设计更容易做代码优化,优化的效果也更好。
代码优化大致可以分为以下两个部分:平台无关部分和平台相关部分
平台无关部分是指一些普适的优化原则。如循环展开,减少分支,内联函数,指针运算,
地址对齐等等。
平台相关部分就是通常所说的汇编代码优化。汇编代码可以对某个平台做最贴心的优化。首先各个平台都有不同的“高性能”指令,如C55的双MAC,ARMV5E的dsp指令,XSCALE的WMMX等。其次,各个平台的流水线都不同,对指令排列有不同的要求,所以在汇编一级可以对指令做最好的调整。再次,只有在汇编一级,才可以抛开编译器,使程序思维最贴近CPU逻辑,并避免一些不必要的计算,带来最好性能。毕竟编译器的智商以及它对程序的了解通常比我们程序员要差一些。
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删