chap5:优化程序性能
来源:互联网 发布:js设置select id设置值 编辑:程序博客网 时间:2024/05/17 01:55
这一章主要讲的是代码级的优化。
5.1、优化编译器的能力和局限性
大多数现代编译器向用户提供了对代码优化的功能,gcc提供了‘O1','O2'和’O3'三项优化控制,Visual studio的优化控制可以在:项目-->properties-->configuration-->c/c++-->optimization中设置优化控制。
但编译器受到妨碍优化的因素(optimization blocker)的阻碍。妨碍优化的因素举例:
1、存储器别名的使用(memory aliasing):如果编译器不能确定两个指针是否指向同一个位置,就必须假设任何情况都有可能,限制了可能的优化策略。eg:
因为f1的引用次数比f2的引用次数多一倍,所以编译器会尝试优化f1,使其达到f2的效果,但如果xp==yp,f1和f2并不等价,从而f1并为得到优化。
2、函数调用:大多数编译器不会试图判断一个函数是否有副作用,编译器会保持所有的函数调用不变。eg:
由于f()改变了counter的值,所以f1和f2并不等价。由于这个原因,,编译器会保持所有的函数调用不变。
包含函数的代码可以通过”内联“函数来优化。
5.2、表示程序性能
程序性能度量标准:每元素的周期数(cycles per element,CPE),通常通过最小二乘方拟合(least squares fit)来得到CPE的有效值。
5.3、程序实例:向量里元素的合并
5.4、消除循环的低效率
每次循环迭代时都必须对测试条件求值,向量的长度并不会随循环的进行而改变,所以把vec_length(v)移到循环外,优化后:
编译器会保持函数调用的存在,所以此处编译器不会优化。
5.5、减少过程的调用
过程调用会带来相当大的开销,而且会妨碍编译器对大多数形式的程序优化。所以把get_vec_start(v)移到循环外,优化后
5.6、消除不必要的存储器引用
CPU从寄存器里读写比从存储器里读写快约100倍。(不考虑cache)
在第i次迭代中,程序读出这个位置处的值,乘以data[i],再将结果存回到dest,每次迭代开始时从dest读出的值就是上次迭代最后写入的值,可以引入一个临时变量acc来消除这样无用的存储i读写。优化后:
5.8、循环展开
循环展开能够从两方面提供程序的性能,一是它减少了不直接有助于程序结果的操作的数量,例如循环索引计算和条件分支(或条件判断);二是它提供一些方法可以进一步优化代码,减少整个计算中关键路径上的操作数量。
思想:循环展开k次,则循环上限为n-k+1; 利用k=2优化后
5.9、提高并行性
在每次计算acc时,不能计算acc的新值。虽然硬件功能单元能够每个时钟周期开始一个新的操作,但是它只会每L个周期开始一条新操作,这里L是合并操作的延迟。注意:IA32指令集只有很少量的寄存器来存放累积的值,如果我们的并行度p超过了可用的寄存器数量,那么编译器会把某些临时值存放到栈中。现在体会到x86-64增加的八个寄存器的价值了。(P359-P360)
利用p=2个累积变量对combine优化:
分析优化结果:下图是每一步优化后combine函数的CPE值(在表格中,下一次优化基于上一次,F*表示float,D*表示double)
5.13、总结/应用
本章描述了许多优化程序性能的基本策略:
1、高级设计:选择合适的算法和数据结构;
2、基本编码原则:
消除连续的函数调用。如果可能将计算移到循环外;
消除不必要的存储器引用。引入临时变量来保存中间结果。只有在最后的值计算出来时,才将结果存放到数组或全局变量中。
3、低级优化
展开循环,降低开销,并且使得进一步优化成为可能(并行);
通过使用例如多个累积变量和重新结合等技术,找到方法提高指令级并行;
用功能的风格重写条件操作,使得编译采用条件数据传送(没仔细看);
- chap5:优化程序性能
- chap5
- Java性能优化:程序优化
- Java程序性能优化 !
- Java程序性能优化
- Java程序性能优化 !
- Java程序性能优化
- Java程序性能优化
- java程序性能优化
- Java程序性能优化
- Java程序性能优化
- Java程序性能优化
- Hibernate程序性能优化
- Java程序性能优化
- Java程序性能优化
- 优化Hibernate程序性能
- c程序性能优化
- Java程序性能优化
- struts1 模拟登录
- HTML5设计原理--Jeremy Keith在 Fronteers 2010 上的主题演讲
- Quartz定时任务学习(一)简单任务
- java IO之装饰设计模式
- Quartz定时任务学习(二)web应用
- chap5:优化程序性能
- 在Ubuntu下安装Kniect+openni+nite
- 对browser扫盲认识
- OpenNI和Kinect安装中文教程(Windows下)
- action向Jsp传值
- CFileDialog类的使用
- C#启用服务 关闭服务 安装服务 卸载服务 收藏
- unix ftp命令介绍
- android真机调试方法