优化程序性能之优化编译器的能力与局限

本章主要探讨内容:使用几种不同的程序优化技术,让程序运行得更加高效,并且在可维护性与性能间达到平衡。

将从以下的几个方面对程序进行优化

  1. 选择合适的算法与数据结构
  2. 尽可能使用使编译器更容易产生高效代码的方式来进行程序编写

程序优化的第一步应当是消除多余的不必要的工作,包括函数调用、条件测试与内存引用等。这些优化不依赖于目标机器。
基于Intel和AMD处理器,本章提出了一种高级模型。还设计了一种图形数据流来对处理器的指令执行形象化,并利用其预测程序的性能。

利用处理器提供的指令级别并行能力同时执行多条指令,提高程序性能。
通过研究程序的汇编代码是理解编译器以及产生的代码如何运行的最有效的手段之一。

不管有什么样的策略,在落实的时候都需要不断地试错、不断地修改源码并分析其性能。

GCC向用户提供了一些对它们所使用的优化的控制。最简单的控制就是指定优化级别。具体内容在GCC手册中有详细的说明。
一般使用级别的优化。

注意,编译器只对程序使用安全的优化
所谓安全的优化,是指优化的结果不会导致任何运行结果的不同或者内容上的歧义。

避免内存别名的出现以及使用restrict进行优化

一个典型的例子——内存别名使用

 

上述代码中,code2更加高效。
code1需要6次内存读取,而code2只需要3次
但是,编译器不会把code1优化为code2的形式——若指针a、指针b指向同一片内存,则code1的结果将与code2产生差异。

这种两个指针可能指向同一个内存位置的情况称之为内存别名使用。编译器必须假设不同的指针可能会指向内存中的同一个位置。

例如以下代码:

 

编译器必须假设指针p、q指向了同一片内存。若p、q内存地址不同,则t的取值为1000,否则为3000。
这就是一个妨碍优化的因素。如果编译器不能确定两个指针是否指向同一个位置,就必须假设什么情况都有可能。

另一个内存对齐的例子是(参考资料

 


平台注册入口