« 上一篇下一篇 »

优化主要来源

如果我们简单地把每个高级语言结构独立地翻译成为机器代码,那么会带来相当大的运行时的开销。下面讨论如何消除这样的低效率因素。在目标代码中消除不必要的指令,或者把一个指令 序列替换为一个完成同样功能的较快的指令序列,通常被称为“代码改进”或者“代码优化”。

局部代码优化(在一个基本块内改进代码)的相关知识已经简单地了解过了。下面我们将处理全局代码优化问题。在全局优化中,代码的改进将考虑在多个基本块内发生的事情。我们会讨论一些主要的代码改进机会。

优化的主要来源

编译器的优化必须保持源程序的语义。除了一些非常特殊的场合之外,一旦程序员选择并实现了某种算法,编译器不可能完全理解这个程序并把它替换为一个全然不同且更加高效的等价算法。编译器只知道如何应用一些相对低层的语义转换。在进行转换时,编译器用到一些常见的性质,比如像i+o = i这样的代数恒等式或使用一些程序语义(如在同样的值上进行同样的运算必然得到同样的结果)。

冗余的原因

在一个典型的程序中会存在很多冗余的运算。有时,在源代码中会用到冗余。比如,程序员 可能发现重新计算某些结果会更为直接和方便,而让编译器去发现实际上只需要进行一次这样 的计算。但更多的时候,冗余性是使用高级程序设计语言编程的副产品。在大部分程序设计语言(不包含C或者C + +,它们允许对指针进行算术运算)中,程序员别无选择,只能使用类似于 4[i][j]或X—f1的方式来访问一个数组的元素或一个结构的字段。

当一个程序被编译后,每一个这样的高层数据结构访问都会被扩展成为多个低层次的算术运算,比如计算一个矩阵4的第(i,j)个元素的位置的运算。对同一个数据结构的访问通常共享了很多公共的低层运算。程序员不知道这些低层运算,因此不能自己去消除这些冗余。实际上,从软件工程的角度看,程序员只通过数据元素的高层名字来访问它们是比较好的做法。这样,程序容易书写,并且更重要的是,程序更容易理解和演化。通过让一个编译器来消除这些冗余,我们在两个方面都得到了最好的结果:程序不仅高效而且易于维护。

« 上一篇下一篇 »