设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客

龙芯2F处理器GCC 4.4优化探秘

2008-10-21 10:40| 发布者: joejoe0332| 查看: 8016| 评论: 3

  作为Linux平台下最常用的编译器,GCC提供了强大的编译能力和良好的平台通用性,其重要性不言而喻。编译优化是它的一大特点,除了可以对软件代码进行不同程度的分析优化外,GCC还可以根据处理器的结构特性在编译中对代码进行有针对性的编排组合,以更加高效地运行于目标平台。目前,处在最后测试阶段的GCC 4.4加入了针对龙芯处理器的编译优化支持,配套文档中也给出了详细的操作说明。针对这一改进,计算机世界实验室于近日进行了一次特别测试,重点研究GCC 4.4为龙芯平台软件环境带来的性能提升。

  测试的软件环境基于3个在龙芯平台上比较常见的操作系统构建,分别是Debian、Gentoo与国产的Linux操作系统“憨牛”。前两者是在世界范围内得到广泛应用的Linux发行版,都拥有独立的软件包管理系统和海量的应用软件。它们的软件包管理模式存在差异,Debian为多种硬件架构提供了编译好的二进制包,为最大程度地保证兼容性,MIPS架构的二进制文件采用最基础的MIPS1指令集架构编译;Gentoo则提倡源代码发行的方式,安装软件时对下载的代码进行本地编译。利用上述特性,我们分别用Debian和Gentoo构建了针对MIPS1和针对龙芯2F、o32模式编译的测试环境。而“憨牛”是国内龙芯爱好者以LFS方式制作的纯64位发行版,我们用它作为龙芯2F、n64模式下的测试环境。这些系统都被安装在硬盘的不同分区中,并将内核统一指定为Server模式的2.6.26.5,编译参数采用“-march=loongson2f -mabi=n64 -O3”。为保证结果的一致性,我们选择截止到测试开始前的最新版本“GCC 4.4 snapshot 20080923”作为统一使用的编译器。如无特别标识,所有测试软件均使用“-O2”参数进行编译。



  为了让测试结果更具普遍性,本次测试的硬件平台也由开发板换成中科龙梦推出的福珑2F-6003迷你电脑。这款产品虽然只有普通光驱的大小,却内置了龙芯2F 800MHz处理器、DDR2-533 512MB 内存和80GB UltraATA 2.5英寸硬盘。板载的Realtek RTL8110SC网络控制器则提供了一个千兆以太网接口,为网络应用做好准备。这款产品配备了一个输出功率为40W的变压器,但在我们的测试中实测功耗从未超过15W。因为低功耗、低噪音等特性,很多用户都将福珑2F-6003当做不掉电的下载机或SOHO服务器使用。


  理论性能测试

  LMbench是一款历史悠久的性能评测工具,被广泛应用于UNIX/Linux环境下的系统性能评估。它包含了一系列测试程序,可以对不同层面、不同子系统进行专项测试。随着应用模式的变化,新版本的LMbench中也不断加入有针对性的测试程序,保持了评估模型的准确性。本次我们采用了LMbench最新的3.07a版,利用其中附带的lat_ops和par_ops两个程序,测试不同指令集版本、处理器类型及ABI模式下指令执行的相关性能,从而考察GCC 4.4对龙芯2F处理器的支持程度。作为对比,我们也将源代码编译为匹配MIPS1指令集与MIPS R4600处理器的版本进行了测试。前者是目前支持MIPS的Linux二进制发行版使用的编译模式,后者是中科龙梦在GCC 4.4发布前官方建议的优化设置。

 

  lat_ops的功能很简单,就是考察对不同变量类型执行操作所需的时间。可以看到,即使针对龙芯2F和R4600处理器进行优化,很多操作所需要的时间也与按MIPS1指令集架构编译后的成绩相差无几。变化主要发生在对64位整型变量的操作方面,测试程序针对龙芯2F与R4600编译后的运行速度普遍有所提高,各别测试结果发生了数量级上的变化。在对64位整型变量进行整数除法与取余数操作时,n32与n64模式下执行速度提高4倍,体现了不同ABI的差异。基本可以认为,对于lat_ops所测试的指令,GCC 4.4针对龙芯2F和R4600处理器进行编译的效果相仿,二者均略优于MIPS1。

 

  与lat_ops相比,par_ops更像是一个进阶测试。通过对前者的修改与扩展,par_ops着力于体现处理器在指令层面的并行处理能力。它使用了一些类似教科书上讲述并行计算时采用的示范代码,只要处理器与编译器支持,就可以以并行方式同步执行,其结果反应了每指令周期不同操作达到的并行度。这部分的测试结果比较混乱,除了一些并行度相同的操作外,很难在其他项目中寻找一个线形的变化规律。纵向的比较反而更容易说明问题,o32模式和针对MIPS1指令集架构编译的代码并行度相对较低,n32模式下针对R4600处理器编译的代码则在很多操作中拥有最高的并行度。GCC 4.4对龙芯2F处理器的优化能力似乎还有提升的空间,虽然n64模式下针对龙芯2F编译的代码执行并行度最高,但在o32和n32模式下,对浮点型变量的操作并行度与R4600还有明显差距。

  总体来说,在指令层面,使用GCC 4.4针对龙芯2F进行优化编译的效果还是比较明显的,这一点在64位环境下尤为突出。我们还使用-O2与-O3参数分别编译了针对龙芯2F、n32模式优化的代码,考察两者之间的性能差异。也许是测试程序的代码太过简单,lat_ops与par_ops靠进一步优化获得的性能提升与编译增加的时间绝不成正比。


  实际应用测试

  接下来进行的实际应用性能测试相信更让人感兴趣。根据现有测试条件,我们选取了一些比较常见的应用作为测试项目,并将它们归纳为桌面与网络两大类。桌面部分包括病毒检测、压缩打包和音频编码三种应用,考量指标是完成任务需要的时间;网络部分则通过在不同系统环境下构建完整的LAMP(Linux/Apache/MySQL/PHP)服务,使用思博伦通信的Avalanche 2500应用层性能测试仪考察不同测试用例的每秒最大新建事务数。

 

  病毒检测软件选用的是比较著名的ClamAV,引擎与特征库统一为测试当天的最新版本。测试用例是一个保存Windows系统下绿色软件的文件夹,内含52个子文件夹,共816个文件,大小为121MB。为加大负载,我们还将此文件夹在Windows下用WinRAR压缩为61.4MB大小的Zip格式文件,执行病毒检测时多了动态解压缩的步骤。从测试结果可以看出,针对龙芯2F、o32模式编译的代码与针对MIPS1指令集架构编译的代码执行效率相仿,后者的综合成绩还略好些;n64模式下的病毒检测速度相对较慢,看来ClamAV涉及到的计算模型并不能从纯64位环境中获益。

  压缩打包测试直接利用了上面的测试用例。我们在bash下通过tar调用gzip,将文件夹打包成一个文件,并记录任务完成所用的时间。在这一环节,64位环境同样没有给应用带来性能提升。针对龙芯2F、o32模式编译的代码执行速度最快,领先MIPS1编译版本十几个百分点,应当是指令集与指令调度方面的原因。

  音频编码的性能差异是实验室工程师最感兴趣的地方。根据以往的测试经验,这也是最能体现架构与指令集进步的部分。除了运算单元的改进,SIMD指令也有可能显著提高编码性能,但这一切都要通过优秀的编译器和适当的算法(代码)联合实现。本次测试我们采用的是著名的MP3编码软件LAME,目标对象是一个131MB大小、16位/44.1KHz的WAV文件,编码参数均为默认设置。可以看到,GCC 4.4针对龙芯2F的编译优化首次起到决定性的作用,即便最慢的o32模式的执行速度也比针对MIPS1指令集机构编译的代码快近50%。为弄清性能提升的主要原因,我们特别编译了一个版本进行对比:针对R4600处理器、n32模式编译的LAME完成编码工作共耗时252秒,看来性能提升的主要原因是使用了MIPS3指令集;而与龙芯2F、n32模式下超过1/10的性能差异,则可能源于不同的指令调度模型和SIMD指令。通过这项测试,我们推断音、视频编解码软件是最值得通过编译优化的一类程序,它们的性能很可能从GCC 4.4中得到质的提升。

 

  为保持评估标准的一致性,我们在网络应用性能测试中沿用了先前的测试方法与测试用例。从结果来看,64位系统环境终于带来了性能提升,各项测试成绩均为第一。针对MIPS1指令集架构编译的LAMP环境表现也令人惊讶,在涉及动态页面解析的测试项中达到了与龙芯2F、n64模式相同的性能。同样是o32,针对龙芯2F编译的LAMP环境则有些令人失望,其表现出来的性能在本次测试中垫底。


  从静态页面的测试结果中可以看出,针对龙芯2F、o32与MIPS1编译的两组环境成绩近乎一致,而针对龙芯2F、n64模式编译的环境性能高出一筹,说明前两者的瓶颈在于o32这种ABI而非内核或编译Apache时指定的指令集。当测试用例转向复杂的动态页面,所有平台都无法突破11/9/43这一成绩,也许这就是处理器的极限?我们测试过的龙芯2F开发板配备了与福珑2F-6003相同的处理器和频率高出13%的内存,结果也只是静态页面处理能力得到小幅提高。

  比起桌面应用,LAMP服务环境相对复杂的多,与内核的关联也更加紧密。这部分我们进行的颇为周折,起初因为各系统环境的内核抢占模式不统一,导致测试结果没有可比性,只能全部复测。不过,这也是第一次通过测试验证了内核几种抢占模式下的特征差异,为选择提供了依据。

 

  做网络应用时,使用Server参数编译的内核状态最为稳定,可以准确找到系统的最大新建事务数,再此基础上哪怕多一个连接请求都会导致访问失败,并且多次测试的复现率可以达到100%。使用Desktop参数编译的内核稳定性稍差,只能将最大新建事务数锁定在一个比较小的范围,且很难通过复测找到一个准确值。我们在这种内核搭配针对龙芯2F、n64模式编译的LAMP环境下,只能将静态页面的新建能力锁定在1200/1180±50这一区域。而使用Low-Latency Desktop参数编译的内核,在搭配针对龙芯2F、o32模式编译的LAMP环境下只能稳定取得一个1100/1050的成绩。如再增加连接请求,非但每一次测试结果都不相同,成功访问事物的响应时间也会出现较大抖动。看来,支持抢占模式的内核虽然大大提升了图形界面下操作的响应时间,却不太适合做网络应用。尤其像静态页面这种Web服务,事物模型简单却为数众多,负载高时抢占内核执行的空隙效果不大,还会带来不小的系统开销。另外,根据复测得到的结果,内核抢占模式的设定对之前在命令行下进行的单任务测试几乎没有影响。

  因为本次测试缺少n32模式的系统环境(针对龙芯2F、n32模式编译的LAME采用静态连接),导致不能确定龙芯平台上最适合实际应用的编译参数,这一点殊为可惜。就目前情况看,我们选择的应用软件都或多或少地从针对龙芯2F处理器的编译中获益。依照惯例,GCC的版本由测试版变为正式版后,编译优化的性能还会有小幅提高,将在几个月内发布的GCC 4.4正式版值得重点关注。

  网络应用与桌面应用往往在运算模型方面相差甚大,受ABI的影响自然也不相同。n64模式在网络应用和o32模式在桌面应用方面的表现值得肯定,但它们占据优势的应用又是彼此的弱势领域。相信每个人都会想到,如果能集合o32与n64的优势就好了。确实,我们也这样想,于是就对兼具n64与o32特性的n32模式又多了那么几分期待。


  测试后记

  这是一次艰苦的测试,我们遭遇了太多的困难。虽然大部分问题都在测试过程中被解决,但也有一些瓶颈始终无法突破,例如实际应用部分缺乏n32模式的测试成绩,就是最大的遗憾。事实上,在测试后期,我们对龙芯系统平台方面的关注度远远超越了GCC。我们暂时无法找到为龙芯打造的n32系统环境,就算采用LFS的方式制作一个测试专用版本,也绝非一件容易的事情。不过通过这次测试,工程师对目前龙芯平台上可运行的系统有了初步了解。他们各自有各自的特色,用户最好根据实际情况进行选择。

  Debian是成熟度很高的Linux发行版,提供了对不同硬件平台的支持。通过强大的软件包管理系统,可以很方便地下载安装针对MIPS1指令集编译的二进制包,过程简单方便,适合普通用户选用。Gentoo的特点则是独具一格的源代码发行模式,操作者通过软件包管理系统下载软件的源代码,再在本地完成编译工作。虽然这比直接下载二进制代码多了一个步骤,但对用户来说是透明的,并没有增加操作难度。环境变量中编译参数的部分是关键,例如本次测试中参数设定为龙芯2F、o32,则最后得到二进制代码都是针对龙芯2F、o32模式编译的。这种方式有助于定制特殊的软件环境,比较适合进行开发或搭建以提供服务为目的的系统平台。不过,目前Debian和Gentoo都不算是正式支持龙芯平台的系统,只有用户群体达到一定规模,才有可能得到官方的支持。

  福珑2F-6003预装的新华华镭操作系统倒是官方支持龙芯平台的Linux发行版,也是原本计划中MIPS1模式的测试平台。我们在安装ClamAV时遇到了很严重的问题:系统提示其依赖的其他软件包版本不符合要求,无法继续安装过程。也就是说,ClamAV在华镭的软件包管理系统中存在但不可用,是一个破损的软件包。相信类似的依赖关系问题还有不少,但维护人员和用户数量方面的原因导致问题很难被及时解决。

  越来越清晰地感觉到,编译器之后,龙芯还剩最后一个关键问题亟待解决,那就是寻找一套功能完善、软件支持丰富、能很好地发挥硬件性能的系统环境。从测试结果看,针对MIPS1指令集编译的二进制代码显然不能很好地发挥龙芯的性能,工作在n64或n32模式下的系统才是未来的发展方向。新系统最好能够与Debian、Gentoo这样的发行版相融合,借助其规范体系与资源积累方面的优势,充分提高平台的易用性。这个工作单靠研发单位的力量是很难完成的,必须在初始阶段就与开源社区相结合,用较长一段时间,逐步构建完善一套适合龙芯平台的系统环境。在这个过程中,每个人既是开发者,也是系统的使用者。

  龙芯的发展,开源社区的力量绝对是关键因素。在与Windows绝缘的情况下,开源社区在软件层面为龙芯提供了强大的支持,这是独一无二的宝贵资源。如果没有这部分支持,龙芯的前景会很难预料。此外,开源社区也孕育着市场机遇,大量的关注者使龙芯有了群众基础,无论是开发者还是使用者,都有可能成为潜在用户。反过来,开源社区通常也很希望得到来自厂商的支持,开发者可以借此机会少走很多弯路,大大加速项目进程。所以,建议有关部门尽可能多地开放龙芯相关资源,为社区工作提供帮助。

  其实,有关龙芯的很多项目(例如上文提到操作系统的打造)都应融入开源社区,成为社区工作的一部分。与独自闷头苦干相比,通过社区看似松散实质紧密的交互式协作,所有人都将收获最大化的成果。本次评测就是一个很好的例子,如果没有来自开源社区的鼎力协助,您绝对不可能看到这么这篇评测报告。有些名字必须被提及:著名龙芯爱好者刘世伟、张乐与孙海勇分别为本次评测制作编译了不同版本的系统和软件,并对整个测试给予了全程技术支持,我们尤其要向他们表示感谢。


  专家点评

  Debian龙芯优化版修改者、维护者  刘世伟

  作为坚持以非盈利模式运作开发的Debian GNU/Linux,对计算机硬件体系结构的支援程度可谓极端丰富。不过,Debian开发团队是以用户群体的规模来分配资源的,这也是MIPS架构被重视程度较低的原因。就算在MIPS体系内,优化与编译也存在着一定的倾向性,用户数量越多,对版本发展的影响力就越大。所以,我认为尽快扩大用户数量是当务之急。只要龙芯有足够庞大的用户群体,相信包括Debian在内的各Linux发行版都会重视起来,对龙芯平台提供更好的支持。

  Debian系统下有2万多个已经编译好的软件包可以直接在龙芯平台上安装运行,不过大部分是针对MIPS1指令集进行编译,理论上无法充分发挥龙芯处理器的性能。好在从Debian 5.0开始,系统内增加了n32与n64的运行库。虽然不是所有的软件包都能在新环境下正常运行,但可正常工作软件的数量保持了一个快速增长的趋势。也就是说,龙芯平台上软件的运行速度将普遍得到改善。

  在针对龙芯的优化尚未成熟的时间里,也可以继续使用Debian提供的二进制包。尤其是面向服务的网络应用环境,针对MIPS1指令集编译的代码在测试中表现并不差。每秒最多可以完成11次Discuz!首页的访问操作,相当于每天最多90万次的动态页面处理能力。如果用eAccelerator进行加速,PHP性能还会有成倍的提高,足以胜任SMB级别的应用。

  “憨牛”龙芯64位Linux发行版开发者、维护者  孙海勇

  这次测试的结果,令人感觉有点意外,但也都在情理之中。

  意外的是,目前无论采用GCC龙芯优化参数针对哪种ABI进行编译,都无法为多数应用带来明显的性能提升。在某些应用领域,优化的结果甚至还不如采用标准MIPS1指令集编译后的表现。这看起来似乎有些令人沮丧,但细想想,也是情理之中的事情。目前,针对龙芯的优化工作才刚刚起步,大量的常用软件并没有进行过代码级别的优化。而编译器本身的优化能力也还比较有限,需要进一步的挖掘。

  LAMP部分的测试结果令人欣慰,64位环境的整体性能略微占据了一些优势,可能更加适合在服务型平台中进行深入应用。如果将测试用例换成压力更大、更加复杂的业务模型,64位环境的优势也许更加明显。此外,64位环境在数值运算方面优势体现得比较充分,可以为科学计算等需要进行大量运算的应用程序带来明显的性能提升。

  测试结果表明,我们的龙芯还有很长的路要走。怎样科学有效地利用现有优势,以及如何不断集中力量克服劣势,是今后能让龙芯走上可持续发展道路所必须深入研究探讨的问题。

  这种侧重于应用方面的测试对于龙芯的发展是有积极作用的,它能让人看到现状与差距,也在一定程度上看清了努力的方向,还能为用户与开发人员提供一定的技术指导。希望这样的测试内容能够越来越丰富。

  Gentoo Linux发行版开发者、中文社区负责人  张乐

  做为一个从很早就开始关注龙芯并贡献龙芯的自由软件社区的参与者,能参与计算机世界实验室的此次测评并受邀撰写此篇评论,甚感荣幸。

  我目前有两台龙芯盒子,皆是中科龙梦公司所赠。一台2E盒子,目前运行着Gentoo中文[1];一台2F盒子,目前主要用来测试GCC 4.4每周发布一次的快照。运行的操作系统都是Gentoo Linux。

  目前尚未正式发布的GCC 4.4将是首个官方正式提供龙芯支持的主流编译器。提供的支持主要包括提供了对龙芯的向量指令的支持以及这些向量指令的intrinsic,增加了龙芯所支持的MIPS4/MIPS5指令集的部分指令,还有针对龙芯的流水线模型和调度器的优化。

  这些支持究竟可以带来多大的性能提升,以及不同的ABI的表现如何,都是我很感兴趣的问题。所以这次测评我也是投入了很多精力,结果也基本如事先所料,龙芯的支持在很多方面得到了正面的反映。ABI方面,在网络应用或科学计算方面,n64当是不二之选;桌面领域,o32也未尝不是一个好的选择,毕竟还有很多程序如果使用64位ABI会出现bug[2]。此次测评的遗憾在于,没有现成的使用n32的二进制Linux发行版,而且也没有足够时间去自己构建一个,而没能完成关于n32 ABI的完整测评。

  值得一提的是,如果应用程序可以使用GCC提供的龙芯向量指令intrinsic(GCC提供的loongson.h头文件中有定义),那么程序表现还会有更高提升。目前似乎还没有音频、视频处理库或软件增加了这方面的支持,这是以后要做的。

  还有就是即使是n64/n32也还存在有一定的问题[3],所以有人提出了NUBI[4][5]。这或许是未来MIPS ABI的归宿,只是最近一两年以来社区里并没有NUBI的任何讨论,不知前景到底如何。

  未来最好能有一个发行版可以提供完美的multilib支持,也就是一个系统里可以同时支持这3个ABI。CLFS已经有文章[6]可以做出这样的一个系统,不过LFS的升级是个很麻烦的问题。Gentoo曾经有人做过这方面的尝试。未来有时间我准备做一做这方面的研究,希望可以搞一个这样的系统出来。

  [1] http://www.gentoo-cn.org

  [2] http://www.linux-mips.org/wiki/TheCaseForN32

  [3] http://www.linux-mips.org/wiki/WhatsWrongWithO32N32N64

  [4] http://www.linux-mips.org/wiki/NUBI

  [5] http://www.linux-mips.org/wiki/IntroducingNUBI

  [6] http://www.linuxfromscratch.org/clfs/view/1.0.0/mips64


  附:关键词

  MIPS

  MIPS是比较典型的RISC微处理器架构,相应产品众多,实际应用广泛。经过多年发展,MIPS指令集也由最初的MIPS1发展到如今的MIPS32与MIPS64。新的指令系统在保证向下兼容的前提下,拓展出了许多新功能,更加符合实际需要。龙芯2F处理器完全兼容MIPS3指令集,能够直接运行任何针对MIPS编译的二进制代码;另有部分SIMD指令,用于同时处理多组相互独立的数据,可以以较小的代价获取某一类应用模型下较大的性能提高。

  ABI

  ABI是应用程序二进制接口的简称,用于标识处理器的工作模式及规范目标文件的编码格式。MIPS指令集架构自MIPS3起正式支持64位工作模式,故编码可以遵从o32、n32与n64等ABI。o32与n64即纯粹的32位与64位模式,二者除指针与变量类型的长度差异外,n64还用寄存器来传递更多的参数,性能有所提高。n32则是32位数据结构和64位指令的结合体,重点在于仅将long long与double类型编译为64位,其余指针与变量类型设定与o32相同。

  性能方面,64位环境并不一定优于32位环境。前者在带来更大地址空间的同时,也带来了成倍增长的系统开销。例如,指针与变量类型的长度变化几乎等同于去掉了处理器上一半的缓存,这对某些运算模型的影响是致命的。

  抢占模式

  抢占模式是内核编译时需要设定的重要参数之一,决定了是否以及如何进行内核级别的抢占。该功能如被启用,意味着调度模块可以在安全的前提下随时抢占内核执行中的任务,而不必等待其执行完毕。虽然这可以有效提高系统的响应速度,但也会对系统的整体处理能力造成影响。

  2.6版的Linux内核提供3个编译选项,分别是禁止内核抢占的Server模式、允许自愿内核抢占的Desktop模式以及允许主动内核抢占的Low-Latency Desktop模式,用户可根据系统用途选择相应的编译参数。为保证图形界面下的操作流畅性,通常会采用Low-Latency Desktop模式对内核进行编译。

  编译器优化

  编译器优化是指在源代码不变的前提下,单纯依靠编译器对源代码进行分析,并在编译时根据参数设定进行不同程度的优化,从而改善程序的执行性能。GCC使用-Ox这一参数来指定优化的程度,常见选项包括O1、O2、O3等。

  O2通常被认为是比较合适的优化级别,GCC除完成O1级别的所有优化工作外,还将根据处理器指令调度等特性进行优化,这与编译时-march选项声名的指令集架构或处理器型号息息相关。O3要做的工作比起O2又多一些,编译所需时间也长得多,并且像函数内嵌、展开可预见循环等工作有点空间换性能的意思。 

酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部