您的位置:首页 > 理论基础

深入理解计算机系统第五章--编写高效程序

2013-03-31 17:55 447 查看
一.编写高效程序需要几类活动:

1.必须选择一组合适的数据结构和算法

2.必须写出编译器能够优化以转换成高效可执行代码的源代码

3.并行

二.阻碍编译器优化的几点:

1.void swap(int* a,int* d){ *a = *a + *b; *b = *a - *b; *a = *a - *b;} 这里编译器无法判断 a==b,若a==b,则第二部开始结果为0了。

2. return f() + f() + f() + f()...;编译器无法判定f()内是否有副作用,如int f(){return count ++;} 但是如果f()是inline的,则编译器还是可以优化的。

三.让编译器能有效的几个点

1.调整代码具有重新结合的特性,通过重新结合,有效减少指令数。

2.增加累计变量到合适的数量,提升并行性(循环展开)。

3.减少数据依赖性,降低存储器影响,如for_each i in arr{arr[i] = arr[i];}。

四.性能提高技术:

1.高级设计:为遇到的问题选择合适的算法和数据结构,特别要警觉,避免使用会渐进地产生糟糕性能的算法或编码技术。

2.基本编码原则: (1)消除连续的函数调用,在可能时,讲计算移到循环外,考虑有选择地妥协程序的模块性以获得更大的效率。

(2)消除不必要的存储器引用,引入临时变量来保存中间结果,只有在最后的值计算出来时,才将结果存放到数组或全局变量中。(这里有个疑惑,是不是应该在尽量少的使用寄存器的情况下才这样做?寄存器使用的过多,会有寄存器溢出,寄存器中的数据会存到栈中。)

3.低级优化: (1)展开循环,降低开销,并且使得进一步的优化成为可能。

(2)通过使用例如多个累积变量和重新结合等技术,找到方法提高指令的并行度。

(3)用功能的风格重写条件操作,使得编译采用条件数据传送。

五.警告

在提高效率时避免引入错误。

--------------------------------------------------------分隔线----------------------------------------------------------------------

通过这章的阅读,对程序的运行有了更深入的理解。

之前在项目组做程序优化时,架构师说,只有算法的优化,才能使得性能有质的改变。

但是阅读这章,发现在编码实现时,一点小小的动作,辅助编译器的优化,就能让程序的性能有质的改变。

如果在编码时,能想着一点编译器可能做哪些动作,那么代码无疑会具有更高的效率。但是有可能某个MDE之类的过来指着你的代码说,代码写的好丑,能合并的状态没有合并。。。而实际上你是特意这样做,试图与编译器达成一个合作。

除了使用数据流对代码进行分析,还有存储器的影响,这些对我都是新观念。以前只是想过,加载需要时间,回写需要时间,但是却从来没考虑过如果数据是相关的,也就是下一次的加载是上一次回写的结果,这个时候影响是很大的。那么在编码设计时,是不是也要多考虑下如何让数据与算法尽量的解耦呢~

//待续
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: