关于编译器优化方面的知识

    一般编译器能够分红前端(FrontEnd/FE)和后端(BackEnd/BE)两个部分,其中前端负责将用户的源代码翻译成一种编译器的内部表示(Intermedium Representation/IR),咱们简称IR. 这个就是一般词法分析,语法分析所作的事情。对于不一样的源代码语言,咱们须要不一样的前端,可是咱们能够经过使用公共的IR,使得对于不一样的语言,可使用相同编译器的后端。而编译器的后端,如今一般分红两个部分,一部分负责同平台无关的优化工做,咱们一般称为中间端(MiddleEnd/ME),另外部分负责同平台相同的优化工做和代码生成(一般指生成汇编语言或直接二进制机器代码),咱们一般称为代码生成部分(Code Generation/CG).前端

    一样,对于不一样的平台(不一样的CPU,不一样的操做系统),咱们须要不一样的代码生成部分,可是整个编译器的中间端能够在不一样的源代码,不一样的平台之间共享。后端

    有一点须要注意的是,这里说的不一样语言,是指像C/C++/Fortran/Pascal之类的静态编译的语言,而不包含像Java/C#之类须要在运行时间再编译的语言(这是由于这两种编译器的实现方法彻底不一样),而对于Java/C#之类的语言,所用的编译器就是另一个话题了,不过其中用到的大部分技术仍是相似的。而我将会把介绍的重点放在编译器的中间端(ME).缓存

    关于介绍编译器优化的书,我推荐你们能够看一下美国的Steven S. Muchnick写的Advanced Compiler Design and Implementation. 国内有影印版,中文名字叫《高级编译器设计和实现》。可是有没有翻译成中文的版本我就不知道了。并发

    而现成的比较好的编译器源代码,我推荐open64,这个能够在http://www.open64.net/上找到,这个编译器的前身是sgi的编译器pro64,后来移植到Itanium芯片上。根据open64网站上的信息,如今能够用于Itanium (IA64), i386 (32x86通用芯片)X86_64(64x86通用芯片)。不过好像只支持Linux (Windows能够试着安装一下cygwin看看).对于语言,它能够同时编译C/C++/Fortran. 在我印象中,这个编译器的前端用的是gcc的前端,也就是说必须安装了gcc才可以使用open64,可是听说编译出来代码的性能比gcc要好不少。工具

   刚才又想到一个问题,到底编译器的定义是什么?什么样的软件才可以称为编译器呢?性能

   一般,编译器应该是一个将一种面向用户的"高级语言"翻译成面向机器的"目标语言"的软件。可是实际上,如今的编译器范畴要远远大于上面的定义。优化

  好比如今的编译器能够支持源代码到源代码的编译。好比open64里面,印象中提供了一个叫ir2cir2f的工具,也就是能够将open64中通过优化的IR从新翻译成C语言或fortran语言(固然翻译过程可能会有错误)。那么将编译器同这个ir2cir2f功能相结合,就能够当作一个从源代码到源代码的编译过程(中间能够有优化)。上面过程能够是同一种语言之间的等价变化,也能够是不一样语言之间的等价变换(不一样语言之间的变化更难,一般因为语言特性的不一样,甚至于有些语句可能没法翻译回去)。网站

   而实际上,不少编译器(特别是用于研究的编译器)都是只支持源代码到源代码的编译过程的,咱们称这种编译器为Source to Source Compiler.spa

  在另一方面,好比Intel推出Itanium的时候,就赶上一个问题。虽然Itanium提供了许多理论上很是优秀的功能,但是实际上,虽然Itanium硬件直接提供了对x86的支持,可是性能不好,而实际上存在的大部分软件都是编译成x86代码,因此Itanium平台上运行软件的速度很是慢。Intel就提供了一种能够在运行时将x86代码从新编译成Itanium代码的软件,这个软件也能够当作是编译器的一种,一般称为Binary Translation.操作系统

这里我想先讨论下一类关于循环语句的一种优化,能够统称为么模变换。

这种循环变换理论上结果很是漂亮,惋惜我认为不少C/C++写的代码因为指针的存在,

编译器没法准确分析数据依赖关系,不少这样的机会编译器都没法真正作掉。

而这种优化每每能够提升代码对缓存的使用,提升指令级并发度,以及提升线程级并行度。

咱们先分析一个最简单的状况。

1.  int a[N][M];

2. 

3.  for(i=0;i<M;i++)

4.    for(j=0;j<N;j++)

5.      a[j]=...;

复制代码

相关文章
相关标签/搜索