使用Intel编译器(4)IPO(1)IPO了解和使用

来源:互联网 发布:云视通网络监控进不去 编辑:程序博客网 时间:2024/05/17 18:02
参考手册:

http://software.intel.com/sites/products/documentation/studio/composer/en-us/2011Update/compiler_c/index.htm


说明:本系列文章为个人笔记,如有不正确之处,请参考官方相关文档,如果错误发现,我会尽量更新修改。另外,以下内容不保证对于所有版本的编译器都正确,编译器的实现也可能有一些变化之处,具体参考官方文档。


更多说明请参考http://blog.csdn.net/gengshenghong/article/details/7034748中补充说明部分。


类似博文可以参考:

http://software.intel.com/zh-cn/blogs/2010/08/13/ipo/

http://software.intel.com/zh-cn/blogs/2010/08/16/ipo-2/


(1)  了解IPO的功能

IPO是Intel编译器的另一个主要优化技术,即Interprocedural Optimizations,过程间优化。

对于包含许多常用中、小函数的程序,特别是循环内包含调用的程序,IPO 可以极大地提高应用程序性能。

IPO对程序进行静态的拓扑的分析(Interprocedural optimizations performs a static, topological analysis of your application!)

IPO优化的内容主要有:
Enabled optimizations:
Procedure inlining (reduced function call overhead)
Interprocedural dead code elimination, constant propagation and procedure reordering
Enhances optimization when used in combination with other compiler features

当然,IPO优化也会包含很多基本的优化技术,比如内联这些,但是IPO是一种过程间的代码分析,会对代码进行全局的分析,可以简单理解为对于一些优化,能进一步优化,比如进一步内联等,下面还会分析IPO的流程。另外,IPO也会受到其它选项影响,比如/Qx、PGO优化(后面会讨论PGO,PS:结合PGO使用IPO,能更好的进行过程间优化,因为PGO是一个动态反馈的过程,IPO能获得更多的程序运行信息)


(2) IPO的流程


IPO 过程要求首先使用 IPO 选项编译源文件,然后创建包含供编译器使用的中间语言 (IL) 的目标 (.o) 文件。进行链接时,编译器合并所有的 IL 信息,并通过分析找出其中有待优化的地方。IPO 过程中所采取的典型优化措施包括:过程内嵌与重新排序、消除死(执行不到的)代码以及常数传播,也就是使用已知的值代替常数。由于添加了多个过程的上下文,可以安全地执行更进一步的优化,因此IPO 可以在过程内级别上执行进一步的优化

很显然,内联,重新排序,常熟传播等这些都是一些基本的优化术语了,即使是HLO或其它的选项也会包含这些优化技术,但是不同的优化(HLO、IPO等)对这些基本优化可能存在更进一步的作用,或者配合使用会得到更好的效果,比如IPO就会在.o文件中增加一些IL信息,从而能更好的优化,如果使用了PGO,编译器还能得到一些程序运行的反馈信息,就能再进一步对IPO得到更好的优化。


(3) IP和IPO

IPO,过程间优化,其实分为两类,IP和IPO。IP优化只针对单个源文件的模块之间的优化,而IPO优化则提供了多个源文件的模块之间的优化。这一点就比较容易理解了。


(4) IPO基本选项的使用

关键还是如何使用IPO,IPO的基本选项主要有:

/Qip和/Qipo:使用ip或ipo优化。

/Qopt-reportn(/Qopt-report-file、/Qopt-report-help、/Qopt-report-phase、/Qopt-report-routine):输出报告。说明:这些函数都是用于和输出优化报告有关的,而且,这里的几个选项输出的报告是所有优化的报告,而不仅仅是IPO的报告。对于auto-par和auto-vec两种优化,前面介绍了其专有的优化报告的选项,而opt-report是所有优化的报告的集合,后面的PGO等也是适用的。


(5) IPO的流程2

上面已经分析了IPO的流程,下面从选项的角度再次分析一下IPO的“流程”。

对于IPO优化,分为两个阶段:编译和链接。编译得到的输出不是一般的二进制的.o文件,而是mock object(带有IL/IR信息的.o文件)(可参考上面给出的类似博文的链接的文章内容)。那么,如果要分开编译和链接,其选项是什么呢?

编译:icl /Qipo /c a.cpp b.cpp c.cpp

Intel编译器在使用IPO对每一个源文件进行编译的时候,不会产生真正的.o文件,只会输出含有IL的mock object信息文件,这些mock objects会比正常的.o文件大很多,这也很好理解,中间包含了很多用于IR信息。

那么,如果希望能输出一个“正常的“中间文件呢,可以使用/Qipo-c选项。这个选项告诉编译器生成真正的obj文件。另外,由于IPO是多个文件之间的分析,所以如果要生成obj文件,只会生成一个,而不会像一般的编译一样为每个文件生成一个obj文件,icl生成的obj命名为ipo_out.obj,类似的如果使用/FA输出asm文件,也会生成ipo_out.asm,Linux上-ipo-S生成汇编。

链接:icl /Qipo a.o b.o c.o或xilink /Qipo a.o b.o c.o

需要注意的是,由于编译后的.o文件并不是真正的obj文件,只能使用Intel的编译器或者链接器来链接,不能使用第三方的编译器(如VS的link.exe,GNU的ld等,PS:对于没有使用IPO优化的中间文件,Intel编译器产生的中间文件是兼容VS和GNU的,所以可以使用它们链接)。所以,对于使用makefile来编译的时候,如果使用了IPO,要注意对应的修改链接器、打包器(xiar for Linux)等等。


(6) IPO性能相关的问题

IPO优化和其它优化选项结合(PGO、HLO、auto-vec等等)一起使用效果会更好,IPO可能为其他的优化提供信息,其它的优化选项也可能对IPO有好处。

IPO对C程序的优化效果可能比C++更好,是因为编译器对C++默认开启了intra-file内联(文件内内联,IP优化),而对于C程序默认没有开启。

可以对程序的一部分(模块)进行IPO优化,另一部分(模块)不使用IPO优化,当然,对整个程序进行IPO优化得到的优化效果是最好的,参考下面的”对大文件/程序采用IPO优化的选项“。


(7) 对大文件/程序采用IPO优化的选项

上面已经说到,IPO只为链接生成一个obj文件(非mock obj),对于一些工程比较大的程序,如果生成一个mock obj文件,可能会有一些问题,可能导致无法使用IPO选项(其实简单的理解,工程太大,生成一个obj文件,那么obj文件可能会太大,超过操作系统可以允许的文件大小)。编译器提供了两个方法来避免这个问题:一种是自动的方式,编译器根据自己的经验来决定生成多少个obj文件;一个是手动的,用户告诉编译器生成多少个obj文件。具体选项如下:

/QipoN:当N为0的时候,和不指定N的效果一样,就是上面的/Qipo选项了,这时候编译器会根据自己的经验生成1个或多个obj文件(所以,反过来说,上面(5)部分对/Qipo的描述都是针对小文件的);当N大于0的时候,编译器生成N个obj文件;当N大于源文件数目的时候,编译器为每一个文件生成一个obj文件,不会生成更多的obj文件。说明:对于N个obj文件,生成的文件命名为ipo_out.obj,ipo_out1.obj,ipo_out2.obj....ipo_objN-1.obj。

/Qipo-separate:如果源文件数目为M,那么相当于/QipoM了,让编译器为每一个源文件生成一个obj文件,也就是生成最多的obj文件数。

/Qipo-jobs:n:这个选项对IPO链接时候指定同时运行的命令或任务数目。简单理解,就是并行的处理obj文件。当然,这个选项会受到上面这些选项的影响,另外,使用这个选项要注意,n不要超过处理器数目,并且保证系统有足够的内存,否则可能会反而增加链接的时间。


总结:这里了解了IPO的基本内容,对于一般的应用都没有问题了,如果还有其它问题,在后面再继续讨论。



原创粉丝点击