全部博文(436)
分类: LINUX
2012-11-26 11:03:14
《深入理解计算机系统》第五章学习报告
11级 赵鑫欢
第五章 优化程序性能
由于第一次独立完成这种专业性较强的书,无论从术语还是知识技能上都很是欠缺,所以读起来有些吃力,仅完成了前十节的学习,也有很多查过资料依然不太理解的地方。
本章讲述了如何优化程序性能。主要阐述编译器的优化和CPU级别的优化。
通过阅读、查询和思考,从本书中我学习了以下几点:
1. 编译器优化程序能力的限制因素:不能改变正确的程序行为;对程序行为、对使用它们的环境了解有限;需要很快的完成编译工作。除此之外,还介绍了存储器的别名使用,由于编译器必须假设不同的指针可能会指向存储器中的同一个位置,这成了主要的妨碍优化的因素。
2. 程序度量的标准:每元素的周期数(CPE)——每个时钟周期的时间是时钟频率的倒数。对于给定响亮的长度,增大程序运行的速度往往通过减少计算的CPE实现。
3. 迭代:执行一遍组成循环的语句块。
4. 消除循环的低效率:利用代码移动。这类优化包括识别出要执行多次但是计算结果不会改变的值。由于每次循环迭代时都必须对测试条件求职,而且向量的长度不会随着循环的进行而改变,所以我们只需要计算一次向量的长度,以后再测试中都使用这个值。方法:将计算移动到代码前面的、不会被多次求值的部分一道前面。
5. 减少过程调用:过程调用会带来相当大的开销,浪费cpu,而且妨碍大多数形式的程序优化。其次,有些程序代码运行的速度比较快,但这是以损害一些程序的模块性为代价的。
6. Told/Tnew的比率——表示性能改进的方法:Told:原始版本所需要的时间,Tnew:修改过的版本多需要的时间。
7. 消除不必要的存储器的引用:使得每次循环迭代中不再需要读和写中间值。由于存储器的别名使用,两个函数可能会有不同的行为,我们可以再变量的最后一个元素和存放结果的目标之间创建一个别名,将结果存放在目标位置中。
8. 理解现代处理器:编译器的优化都不依赖于目标机器的人格特性,知识简单的降低了过程调用的开销,一级消除了一些重大的妨碍优化的因素,这些因素会给优化编译器造成困难。而现代微处理器采用了复杂的硬件,试图使程序性能最大化,在实际处理中,同时对多条指令求值。采用惊喜的机制来确保并行执行的行为,能更好获得机器级程序要求的顺序语意模型的效果。
9. 超标量:可以再每个时钟周期执行多个操作,而且指令执行的顺序不一定与他们在汇编程序中的顺序一致
10. 分支预测:当程序遇到分支时,可能有两个前进的方向:选择分支和不选择分支。分支预测技术可以使处理器预测是否选择分支,同时预测分支的目标地址。
11. 现代处理器整体设计分两个部分:ICU(指令控制单元)——负责从存储器中读出指令序列,并产生一系列基本操作和EU(执行单元)——完成这些操作,以及指出分支预测是否正确。
12. 指令告诉缓存:一个特殊的告诉缓存器,包含最近访问的指令。
13. ICU从指令告诉缓存中读取指令。ICU会在当前正在执行的指令很早之前取指,有足够的时间对指令解码,并把操作发送大EU。
14. EU接收来自指令读取单元的操作。
15. EU接收来自指令读取单元的操作。要判断分支预测是否正确,若预测错误会导致很大的性能开销。
16. 退役单元:ICU中记录正在进行的处理,并确保它遵循机器级程序的顺序语义。它包含寄存器文件,包含整数和浮点数寄存器,指令解码时,关于指令的信息被放置在一个先进先出的队栈中。
17. 功能单元的性能:每个操作都是有两个周期计数值来刻画的——执行时间(一条操作的总周期数)和发射时间(连续的、独立的操作之间的周期数)。处理器的性能的限制因素:功能单元的执行时间、吞吐量、程序中的数据相关性(从一次迭代的操作数到另一次迭代的操作数)。
18. 处理器性能的约束限制:程序中的数据相关性迫使一些操作延迟直到操作数呗计算出来;资源约束限制了在任意给定时刻能够执行多少个操作;分支预测逻辑的成功限制了处理器能够在指令中超前工作以保持执行单元繁忙的程度。
19. 降低循环开销:利用循环展开的技术——在一次迭代访中访问数组元素并做乘法,得到的程序需要更少的迭代,从而降低了循环的开销。
20. 净CPE:过程需要的总周期数除以元素的个数——当向量长度不能被展开度整出时,需要完成所有剩下的元素,因而引入净CEP。对于长向量,CPE和净CPE的差别很小,但对于短向量,影响很明显。
21. 提高并行性:程序是受功能单元的执行时间限制的,而处理器的几个功能单元式流水线化的,它们可以在一个操作完成之前开始一个新的操作。
22. 循环分割:通过将一组合并操作分割成两个或更多的部分,并在最够合并结果来提高性能。
23. 寄存器溢出:若并行度超出了可用的寄存器顺利昂,编译器会诉诸于溢出,将某些临时值存放到栈中,这种情况会使性能几句下降。
遇到的问题:
1. 完全没有处理器运行方面的概念
2. 图5.10的过程如何就实现了每次循环迭代中不再读和写中间值?
3. 对于程序的剖析方面有种囫囵吞枣的感觉,不是很深入细腻。
4. 存储器的别名使用时怎样产生的?
5. 资源约束下的操作调度室怎样实现的?
6. 怎么能知道时钟频率?