您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > 系统结构实验四编译器对系统性能的影响实验
1实验四:编译器对系统性能的影响实验一、背景知识现代电子数字计算机的基本设计思想可以归结为两句话,就是“存储程序,程序控制”。存储程序是指用户想让计算机完成的任何任务都要事先写成程序存储在计算机中,而程序控制则是说计算机所做的任何事情都是CPU通过执行程序来实现的。也就是说,当我们使用计算机时,必须首先以写程序的方式告诉计算机做什么以及怎样做,计算机才能按我们的要求完成交给它的任务。一般情况下我们之所以不写程序就可以轻松使用计算机,是因为很多程序别人都已经写好了,我们只是无偿(几乎是)利用了别人的劳动成果而已。可见写程序是非常重要的。用CPU直接能识别的语言(机器语言)编写程序非常困难,因此大部分程序都是人们用能够帮助记忆的符号(汇编语言)或接近自然语言的编程语言(高级语言)来完成的,这种用汇编语言或高级语言编写的程序必须经编译器翻译成机器语言才能让CPU执行。由此可以认为,机器语言(指令集结构)就是编译器的目标,计算机系统的性能能否充分发挥,在很大程度上受编译器的影响。假设你要在Intel486机器上用C语言开发一个软件,你首先需要编写一个基于Intel486指令系统的C语言编译器,该编译器知道Intel486CPU执行指令的特点及全部的486机器指令,因此该编译器能将你的C语言源程序高效、最优的翻译成最适合Intel486CPU执行的目标代码。当Intel586上市后,因了兼容性你的基于486的C语言编译器也可以在586上用,但效率却不高,因为该编译器并不知道586新增的功能和指令,它仍然把C语言源程序翻译成基于486的目标代码,相当于你把586当作486来用一样。现在大家普遍使用的Windows下的TurboC,其编译器可能是基于386的,相当于我们把P4当作386用一样!当然这仅指指令系统,毕竟P4的主频和386不可同日而语,更何况还有主存容量呢。好在目前计算机系统结构的现状是CPU时钟足够多,内存容量也足够大,问题在彼此的速度匹配上。一方面,目前程序设计语言的发展方向是更多的考虑软件设计的易用性(可视化界面)、复用性(面向对象)、安全性(有待商榷)和正确性,从而使程序设计语言离底层硬件越来越远。另一方面,硬件设计目标只有一个,那就是采取各种加快执行指令的措施来提高速度。编译器处在中间,面对越来越复杂的软件编译优化越来越困难,面对层出不穷的硬件架构,越来越难适应,其位置更显重要。从某种角度讲,我们使用计算机是最浪费的,使用很少的2CPU时钟(10%左右),没有利用硬件提供的很多优秀技术等等,只是速度掩盖了一切。因此,编译器对系统结构的影响是很重要的。一方面,计算机系统结构设计要充分了解现代编译技术,因为系统结构设计的新技术要靠编译器去应用,而不是用户,比如:一般而言,CPU中寄存器个数越多越好(它比内存单元速度快嘛),但如果编译技术利用不上,也是白搭。用户不会在程序中说要用那些寄存器,甚至用户不知寄存器为何物也能写出很好的程序(是不是有些滑稽?);另一方面,编译器也要与时俱进,尽可能的改进编译优化技术来全面利用系统结构提供的新功能。本实验通过两个比较典型的C语言编译器对同一个C语言源程序的不同编译结果,使大家对编译器影响系统性能的程度有一个感性的认识,尽管速度可以掩盖一切,但是我们应该更加专业的使用计算机。二、gcc简介Linux系统下的gcc(GNUCCompiler)是GNU推出的功能强大、性能优越的多平台编译器,是GNU的代表作品之一。gcc是可以在多种硬件平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比要高20%~30%。gcc编译器既能将C、C++语言源程序直接编译成可执行文件,也可以只编译成目标代码,还可以将多个目标代码编译、连接成可执行文件。gcc的编译过程需要经历四个相互关联的步骤:预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和连接(Linking)。gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。接着调用cc1进行编译,这个阶段根据输入文件生成以.o为后缀的目标代码。汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,以.S为后缀的经过预编译的汇编语言源代码文件和以.s为后缀的汇编语言源代码文件经过预编译和汇编之后都生成以.o为后缀的目标代码。当所有的目标代码都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。在连接阶段,所有的目标代码被安排在可执行文件中的恰当的位置,同时可执行文件中所调用到的库函数也从各自所在的包中连到合适的地方。在使用gcc编译器时,我们必须给出一系列必要的调用参数和文件名称。gcc编译器的调用参数大约有100多个,其中多数参数我们可能根本就用不到,这里只介绍其中最基本、最常用的参数。gcc最基本的用法是:gcc[options][filenames]其中options就是编译器所需要的参数,filenames给出待编译的文件名称。-c,只编译成目标代码,不连接成为可执行文件,通常用于编译不包含主程序的子程序3文件。-ooutput_filename,给出可执行名称为output_filename。如果不给出这个选项,gcc就生成缺省的可执行文件名a.out。-g,产生符号调试工具(GNU的gdb)所必要的符号资讯,要想对源代码进行调试,我们就必须加入这个选项。-O,对程序进行优化编译、连接,采用这个选项,整个源代码会在编译、连接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是,编译、连接的速度就相应地要慢一些。-O2,比-O更好的优化编译、连接,当然整个编译、连接过程会更慢。-Idirname,将dirname所指出的目录加入到程序头文件目录列表中,是在预编译过程中使用的参数。C程序中的头文件包含两种情况:A)#includemyinc.hB)#include“myinc.h”其中,A类使用尖括号(),B类使用双引号(“”)。对于A类,预处理程序cpp在系统预设包含文件目录(如/usr/include)中搜寻相应的文件,而对于B类,cpp在当前目录中搜寻头文件,这个选项的作用是告诉cpp,如果在当前目录中没有找到需要的文件,就到指定的dirname目录中去寻找。在编译程序时,如果我们需要的这种包含文件分别分布在不同的目录中,就需要逐个使用-I选项给出搜索路径。-Ldirname,将dirname所指出的目录加入到程序函数库文件的目录列表中,是在连接过程中使用的参数。在预设状态下,连接程序ld在系统的预设路径中(如/usr/lib)寻找所需要的函数库文件。这个选项告诉连接程序,首先到-L指定的目录中去寻找,然后到系统预设路径中寻找,如果函数库存放在多个目录下,就需要依次使用这个选项,给出相应的存放目录。上面我们简要介绍了gcc编译器最常用的功能和主要参数选项,更为详尽的资料可以参看Linux系统的联机帮助,即用mangcc命令。gcc编译器如果发现源程序中有错误,就无法继续进行,也无法生成最终的可执行文件。为了便于修改,gcc给出错误资讯,我们必须对这些错误资讯逐个进行分析、处理,并修改相应的语言,才能保证源代码的正确编译连接。gcc给出的错误资讯一般可以分为四大类:第一类:C语法错误。这种类型的错误,一般都是C语言的语法错误,应该仔细检查源代码文件中提示给出的第n行及该行之前的程序,有时也需要对该文件所包含的头文件进行检查。有些情况下,一个很简单的语法错误,gcc会给出一大堆错误,我们最主要的是要保持清醒的头脑,不要被其吓倒,必要的时候再参考一下C语言的基本教材。第二类:头文件错误。4这类错误是源代码文件中的包含头文件有问题,可能的原因有头文件名错误、指定的头文件所在目录名错误等,也可能是错误地使用了双引号和尖括号。第三类:库文件错误。这类错误是与目标文件相连接的函数库有错误,可能的原因是函数库名错误、指定的函数库所在目录名称错误等,检查的方法是使用find命令在可能的目录中寻找相应的函数库名,确定库文件及目录的名称并修改程序中及编译选项中的名称。第四类:未定义符号。这类错误是在连接过程中出现的,可能有两种原因:一是使用者自己定义的函数或者全局变量所在源代码文件,没有被编译、连接,或者干脆还没有定义,这需要使用者根据实际情况修改源程序,给出全局变量或者函数的定义体;二是未定义的符号是一个标准的库函数,在源程序中使用了该库函数,而连接过程中还没有给定相应的函数库的名称,或者是该库文件的目录名称有问题,这时需要使用库文件维护命令ar检查我们需要的库函数到底位于哪一个函数库中,确定之后,修改gcc连接选项中的-L项。三、icc简介正如前所述,gcc是非常著名、功能强大且能够跨越多平台的基于Linux的C语言编译器,但这种大而全的做法势必造成gcc在针对某个具体的平台时,其性能不是最好的,尽管gcc可用不同级别的参数进行优化,但这是以时间为代价的。而icc则是Intel专门为其CPU打造的C语言编译器,显然,在Intel平台上,icc应该最好(不是更好)。gcc由Linux系统本身自带,而icc则需要单独下载安装。我们花了很长时间才找到一个免费Linux版本的icc,且没有详细的使用说明,只知道一些最基本的用法,但这对我们的实验已经足够。可以从以下地址下载icc:,在“软件”/“编程”/“Intel的C编译器”下。首先建立子目录/usr/icc,将icc(文件名为l_cc_pc-8.1.028.tar.gz)下载至该子目录。下面说明该软件的安装过程:扩展名为.gz的文件是一个压缩包,需要用命令gzip解压,具体命令格式为:gzip-dl_cc_pc-8.1.028.tar.gz解压后的文件名为l_cc_pc-8.1.028.tar,该文件是一个备份包,需要用命令tar解开备份包,具体命令格式为:tar-xvfl_cc_pc-8.1.028.tar该命令建立子目录l_cc_pc-8.1.028并将解包后的文件存放在该子目录下,进入到该子目录下执行安装命令./install.sh即可,该安装命令将icc安装到/opt/intel_cc_80子目录下面,其中编译命令icc的执行代码在/opt/intel_cc_80/bin下面,为了将/opt/intel_cc_80/bin设置成缺省5子目录以方便使用icc,需要在文件/etc/profile的最后添加以下语句:exportPATH=$PATH:/opt/intel_cc_80/bin。我们在机器210.26.100.50上也提供了Linux下icc的远程安装,可按以下步骤进行:①在本地以root身份登录;②添加帐号redhat;③用ftp方式下载安装文件(粗体为需要通过键盘输入的内容):[root@p24root]#ftp210.26.100.50Connectedto210.26.100.50(210.26.100.50)220(vsFTPd1.2.0)Name(210.26.100.50:root):redhat331Pleasespecifythepassword.Password:123456230Loginsuccessful.RemotesystemtypeisUNIX.Usingbinarymodetotransferfiles.ftpcd/grid-ftp/pub/icc250Directorysuccessfullychanged.ftplsftpgetl_cc_pc_8.1.028.tar.gzlocal:l_cc_pc_8.1.028.tar.gzremote:l_cc_pc_8.1.028.tar.gz227EnteringPassiveMode(210,26,100,50,58,54)150OpeningBINARYmoded
本文标题:系统结构实验四编译器对系统性能的影响实验
链接地址:https://www.777doc.com/doc-2102337 .html