ICC GCC傻傻分不清?聊一聊编译器那些事儿
CPU这东西,大家除了关注工艺、主频、核心数量等规格信息之外,更在意的应该就是性能表现了。反应CPU性能的测试可谓是相当多样,但要说起最权威的,那就不得不提SPEC
CPU测试了。
SPEC的全称是Standard Performance Evaluation Corporation,翻译过来是标准性能评估组织,它是一个全球性的第三方非营利性组织,由计算机厂商、系统集成商、大学、研究机构、咨询等多家公司组成,目标是建立、维护一套用于评估计算机系统的标准。
在CPU性能测试上,SPEC CPU 2006是SPEC组织推出的最新版的软件(上一个版本SPEC CPU 2000已经基本没有人用了),同时也是最受行业认可的测试软件。SPEC CPU 2006包括了CINT2006和CFP2006两个子项目,前者用于测量和对比整数性能,而后者则用于测量和对比浮点性能。在各种处理器的SPEC CPU 2006测试结果上,我们往往会看到ICC或是GCC的字样,那么ICC和GCC又分别代表什么呢?
ICC:全称Intel C++ Compiler,是Intel开发的C/C++/Fortran编译器套装,适用于Linux、Microsoft和Mac OS X操作系统,没有非IA指令集版本(就是说仅供x86架构CPU使用)。ICC广泛应用于高性能计算、分布式计算等商业计算领域,其向量化和并行化性能是业界的标杆,能够充分发挥现代处理器的特性。
ICC编译器套装提供两个版本,针对高性能计算机测试采用前者,而后者面向嵌入式及移动设备
GCC:全称GNU Compiler Collection,GNU编译器套装,是广泛应用的Linux系统的默认编译器(特别是用于编译Linux内核)。GCC能够支持多种架构的处理器,跨平台特性相对出色。不过,GNU组织要求全部的代码由自己完成(防止版权问题),所以GCC虽然有广泛的硬件支持,但是在各硬件平台上却并不是性能最优的编译器。
GCC官方LOGO
到底啥是编译器?
所谓编译器,就是将“一种语言(通常为高级语言)”翻译为“另一种语言(通常为低级语言→汇编语言)”的程序。它的主要工作流程:
高级语言源代码→预处理器→编译器→汇编语言,汇编语言再经过汇编器→目标文件→链接器生成可执行程序。
在这个流程中,高级语言指的就是源代码,如Pascal、C、C++、fortran、Java等,而目标文件指的是包含CPU可以执行的二进制指令的集合。也就是说,编译器起到的作用就是将程序源代码“翻译”成汇编语言,既然是“翻译”工作,往往就有Good和Better的区别,而从上面的介绍我们能够看出,不同的操作系统,能够使用的编译器是不同的,那这个编译效率自然也就存在差异。
同时,CPU也是区分不同架构的,比如x86、MIPS、ARM、Power等等,不同架构的CPU往往运行不同的操作系统,如x86架构CPU可以运行Windows、Linux(Android)和Mac OS X,而MIPS等其他架构CPU往往只能运行基于Linux开发的操作系统。
所以,不同架构的CPU,根据适合的操作系统,在SPEC CPU测试过程中编译器的选择上是不一定是唯一的,而选择哪一种编译器,站在CPU研发者的角度上,无疑会选择能让CPU性能发挥到最大的编译器。
ICC | GCC | |
x86+Windows | √ | √ |
x86+Linux | √ | √ |
PPC/MIPS+Windows | 不存在 | 不存在 |
PPC/MIPS+Linux | × | √ |
通过前面对ICC和GCC的解读,不难看出两者的区别。ICC和GCC都可以运行在Windows和Linux下,Intel是x86架构CPU的老大,配合x86架构CPU开发了ICC,能够最大程度的发挥出x86架构CPU的真实性能。GCC能够配合更多种类架构的CPU加以使用,适用平台更广,但从CPU性能发挥的角度上看,大而广很难和专而精比拼。
但是,综合x86 CPU和Windows系统的市场占有率这两个因素来看,在CPU测试过程中,ICC和GCC的采用率又是怎样呢?
第三方商业机构更多采用ICC,GCC寥寥无几
SPEC官网上公布着大量的专业机构测试结果供大家研究分析,笔者选定了全部的整数单任务测试结果进行分析,通过爬虫抓取了约8600个测试结果,并对测试中使用的编译器进行了数据统计:
结果是使用ICC编译器的测试结果高达95%,而GCC不足0.1%。这些测试结果基本都是独立的第三方商业机构的测试结果,具有很高的参考价值。数据显示,ICC编译器的使用在SPEC CPU 2006测试中具有压倒性的优势,而GCC则几乎没有商业机构使用。
上述统计还反映了一个事实,就是Intel和AMD的x86架构处理器在桌面及服务器领域的垄断性优势。而从其中非x86架构CPU的测试结果来看,仅剩的数个测试成绩,Power、Sparc全部使用的是针对自家指令集优化过的编译器,而非GCC,这也侧面反映了GCC“大而广”的一些问题。
产生这个现象的原因要从SPEC CPU测试成绩产生方法来说起:SPEC组织使用一台1997年的Ultra Enterprise 2主机(处理器为296MHz UltraSPARC II Processor)作为参考对象,在其上运行了全部的SPEC CPU 2006子测试,并把每一项的测试结果的用时(中间数)定位系数1。
实际测试中,假定被测试的CPU运行某项子测试的用时为A,而Ultra Enterprise 2主机同一项子测试用时为B,则用B/A,即可得到被测试CPU该项子测试的成绩,而各子测试成绩的几何平均值记为总成绩。
即SPEC各子项成绩是相对于Ultra Enterprise 2计算出来的(Ultra Enterprise 2各项成绩计为1,总分也是1)。
从中可以看出的是,作为参考成绩的测试结果也并没有使用GCC,而是Sparc自家的编译器。
ICC GCC哪个更好?
实际上,SPEC CPU测试的是应用程序的运行时间,这个是被测机器处理器、缓存、内存、编译器、操作系统等等部分性能的综合体现,并不是某个编译器或者某个CPU的单独测试结果,而且软硬件平台综合体现的结果,即按照官方规则正确跑出来的分都是可比的。SPEC CPU测试结果追求的是程序运行用时越短越好,测试成绩的优劣固然重要,但是编译器的真正的用途是“翻译语言”,在同样的硬件平台(CPU)下,“翻译”的越快就可以理解为应用启动或进行某种运算的用时更少,这就是选择编译器的重要性,也是现代应用优化的方向。
拿ICC和GCC相比,ICC是针对x86架构CPU使用的编译器,ICC在现代高性能计算领域广泛使用的向量化、并行化能力较强,而GCC作为跨平台性的编译器,在这方面性能较差,但是针对某些偏门的CPU指令集而言,GCC是唯一的选择。
ICC、GCC两者广泛应用于商业环境中、都会被应用于处理器、OS及编译器开发、测试之中。有些爱好者担心ICC过度优化,结果不准确,其实这大可不必。SPEC CPU是有严格的测试标准的,每一项测试都要求严格和参考结果一致,任何过度优化导致的程序计算错误都不会被计算在结果之中。实际上,ICC在多年的高性能计算领域已经证明了自己的可靠性,而GCC在过往版本中,也会有编译出错、计算结果不正确等现象。
ICC GCC区别好比如此 懂得人自然懂
最后笔者想要强调的是,硬件平台性能发挥需要合适的编译器来加以配合,合适的才是最好的,如果编译器不能合理使用,那又有何意义呢?
评论