代码优化:有效使用内存CODEOPTIMIZATION:EFFECTIVEMEMORYUSAGEKrisKaspersky著透视优化技术细述代码实例量析代码性能对比优化方式优化概述尽可能保持与硬件无关必须使程序性能的提高不少于20%应该使代码修改起来毫不费力优化原则优化的重要性减小处理器负担用户对运行期望值高优化并没有想象的那么费劲程序剖分程序剖分就是指找出程序中的热点的过程热点是指程序中需最长执行时间的代码程序剖分剖分的主要目标:从总体上考察标定应用程序的运行时性能程序剖分剖分的过程:举例分析:使用VC++提供的profile.exe剖分一段程序得到如下结果:程序剖分从上面结构中可知:Main函数、gen_pswd函数与do_pswd函数都可看作热点程序剖分分析可得:若gen_pswd函数与do_pswd函数是相互独立的,则它们是两个热点。若不独立,如存在父子关系则可知只有子函数是热点。程序剖分常用剖分软件:IntelVtuneAMDCodeAnslystMicrosoft的profile.exe内存优化关于内存优化作者给出了几条建议如下:内存优化具体内存优化的操作:1.展开循环2.消除数据的相关性3.数据并行处理4.优化引用数据结构5.减小数据结构尺寸6.数据对齐………………内存优化:展开循环具体做法:例如:for(a=0;a666;a++){x+=p[a];}for(a=0;a666;a+=2){//注意,循环展开以后,执行步骤增加了。x+=p[a];x+=p[a+1];//这是加倍的循环体//循环计数值进行了调整}展开内存优化:展开循环循环展开的好处:实验表明:内存优化:消除数据相关性如果一个RAM单元含有另一个RAM单元的地址,则CPU不能并行的处理它们,在得到地址之前需等待。举例如下:While(next=p[next])与While(a=p[next++])对比内存优化:消除数据相关性•While(next=p[next])由于在处理器得到next变量值之前,便不能加载下一个单元。•While(a=p[next++])当处理器加载p[next]时立即将next加1,处理器便可以向芯片组接着发出请求,故可以看作并行处理,从而达到程序优化的目的内存优化:数据并行处理在大多数情况下,并发读取两个相邻单元的企图会向内存子系统发出一个请求(而不是想象中的两个)处理器在每次存取内存时,都向芯片组发送一个请求,这样总线上存在多个重叠的查询与响应,因此几乎可以达到并行的处理。内存优化:数据并行处理举例如下图可见:并行处理时,几乎可以达到并行的处理多趟循环。消除数据相关性分裂法:内存优化:优化引用数据结构并且由实验表明:好的优化策略是将一个列表分裂为6个独立的列表。这种方法适用于各种不同的数据类型,并不局限于列表将几兆字节的变长文本串绑定在一起的列表分裂成多个按行加以处理的独立列表由于处理速度预处理增量成反比,所以在内存中的数据必须经可能紧密的存放在一起内存优化:减小数据结构的尺寸待优化…………优化后:内存优化:减小数据结构的尺寸在设计方面为避免突发周期从一个随机的地址开始,让该周期自动的与处理器上的32B或64B的边界对齐内存优化:数据对齐高速缓存与存储器存取的优化具体操作方法:1.处理数据的尺寸对性能的影响2.数据对齐效率3.二维数组的处理高速缓存优化:处理数据的尺寸对性能的影响高速缓存优化:处理数据的尺寸对性能的影响•实验表明当要处理的数据大小超出高速缓存的尺寸后,处理时间将急剧增加。•改进算法以便所有密集处理的数据能够放在一级高速缓存,或至少能放在二级高速缓存中高速缓存优化:数据对齐效率高速缓存优化:数据对齐效率由上图可以看出,只有当数据块超越32B、64B或者128B的高速缓存行的边界时,数据读操作将花费6~12个时钟。出现这种情况是因为处理器不能在一个时钟周期中同时读取两个高速缓存行这种数据块称为分行数据高速缓存优化:数据对齐效率1.数据自行对齐2.使用编译器对数据3.优化对齐高速缓存优化:数据对齐效率1.数据自行对齐2.使用编译器对数据3.优化对齐高速缓存优化:二维数组的处理数组的二维性所产生的问题在于如何执行计算:按行还是按列进行计算?对于无法放在一级高速缓存(特备是无法放在二级高速缓存)的大型多维数组按行处理。若放得下按行或列处理均可。总结这本书主要讲解的内容是内存和高速缓存的优化,在讲这之前先讲解了优化的途径,需要找到消耗内存最多的代码段,即找到热点。热点的寻找需要使用软件来配合,书中介绍的软件是IntelVtune、AMDCodeAnslyst和Microsoft的profile.exe。内存优化有多种方式,例如展开代码中循环,简单的将就是将循环递增语句a++变为a+2,a+4,a+8等。