将陆续上传本人写的新书《自己动手写处理器》(尚未出版),今天是第二篇,我尽量每周四篇
第1章 处理器与MIPS
时间开始了!
——胡风 · 1949
让我们以一句诗意的话,开始本书的阅读。
时间从1971年11月15日开始,那一天,Intel发布了世界上第一款单芯片微处理器4004。
1.1 计算机的简单模型
计算机很复杂,可以听歌、看电影、上网、玩游戏,内部是怎么工作的,这个问题太可怕了,太复杂了。
计算机很简单,只有加、减、乘、除、逻辑、移位、转移、存储、加载等几类可以做的操作,太简单了。
复杂?简单?其实取决于个人对事物的认识程度,认识的越多,了解的越深刻,那么就越接近本质,而本质往往都是简单的,比如大名鼎鼎的质能方程,一个简单的式子就解释了质量与能量的关系。
计算机就是一台计算的设备,而且是一台很基础的计算设备,只能计算小学数学课堂上讲授的四则运算,再加上一些并不复杂的与、或、非等逻辑运算,其余诸如平方、开方、微分、积分等等都是做不了的。有读者会有疑惑,你说的太简单的了吧,别急,且听我慢慢道来。
1.1.1 计算机的简单组成模型
计算机的组成有三大部分:处理器(CPU:Central Processing Unit)、输入输出(I/O:Input/Output)、存储器(Memory)。处理器从存储器中获取指令,然后按照指令执行一定的操作,输入输出用来提供运算数据、显示运算结果。如图1-1所示。
存储器中存储的是指令,指令就是一条运算命令,比如:将a与b相加,结果存储到c中,处理器按照命令执行即可。目前的计算机是一个二进制的世界,所有的信息都是用0、1组合来表示的,所以一条指令就是一串0、1编码,正如图1-1中所示。处理器内部具有译码功能,用来解释接收到的0、1编码表示的运算类型,据此进行运算。
1.1.2 计算机的简单使用模型
我们使用计算机上网、办公,都是通过一定的应用程序实现的,而这些应用程序实际就是一批指令的集合,当然,这里的“一批”指的是指令的数目庞大,实际上种类是非常少的,只有几百条,常用的也就几十条。通过这些指令的组织、配合,就实现了目前丰富多彩的应用。
理论上,可以直接使用0、1编码进行程序设计,但是那样显然太不方便、容易出错,于是人们使用一些助记符来表示各种指令,这就是汇编指令,使用汇编程序将汇编指令翻译为计算机可以识别的0、1编码,后来,又发明了高级语言,其语法、使用方式比汇编更加方便、更加易于理解。一般使用编译程序将高级语言编写的程序翻译为汇编指令,然后再使用汇编程序将其翻译为0、1编码。本质上是一样的。如图1-2所示。
这就是计算机的简单使用模型,无论是视频软件、浏览器,还是其他任何软件;无论是使用C#开发、Java开发,还是使用任何其他语言开发;无论是在Windows环境下运行、Android环境下运行,还是在其它任何平台下运行;无论是在ARM处理上运行、Intel处理器上运行,还是在其它任何处理器上运行;无论是在银河二号这样的大型机运行、个人使用的PC机上运行,还是在其它任何机器上运行,都遵循这样的一套使用模型。
总结一下,计算机只识别0、1编码串,任何程序最终都要转变为0、1编码串,而且0、1编码的种类是有限的,计算机按照0、1编码的命令进行工作。这样一说,读者应该觉得计算机很简单了吧。
在计算机中处于核心地位的是处理器,也称为CPU,作用是识别0、1编码,据此进行各种运算和数据处理。本书的目标就是实现一个CPU。
1.2 架构与指令集
类似于不同国家的人使用不同的文字,不同的处理器也使用不同的指令,这样,为处理器A编写的程序不能直接在处理器B上使用,需要重新编写,然后再次编译、汇编后才可使用,减低了软件的移植性。显然,极为不便。
IBM为了让自己的一系列计算机能使用相同的软件,免去重复编写软件的痛苦,在它的System/360计算机中引入了指令集架构(ISA:Instruction Set Architecture)的概念,将编程所需要了解的硬件信息从硬件系统中抽象出来,这样软件人员就可以面向ISA进行编程,开发出来的软件不经过修改就可以应用在符合该ISA的所有计算机上。ISA用来描述编程时用到的抽象机器,而非这种机器的具体实现,从软件人员的角度来看,ISA包括一套指令集和一些寄存器,知道它们就可以编写程序了。
与ISA对应的一个概念是微架构(Microarchitecture),后者是前者的一个实现,比如Intel的许多处理器都是遵循x86的ISA,但是每一款处理器都有自己的微架构。ISA好比是设计规范,微架构则是具体实现,同样的ISA,不同的微架构,会带来不同的性能。
1.2.1 CISC与RISC
从大的方面,根据ISA的不同可以将计算机分为两类:复杂指令集计算机(CISC:Complex Instruction Set Computer)、精简指令集计算机(RISC:Reduced Instruction Set Computer)。主要区别是,CISC的每条指令对应的0、1编码串长度不一,而RISC的每条指令对应的0、1编码串长度是固定的。
在计算机发展的早期,人们使用汇编语言编程,偏好强大好用的指令集,处理器的设计人员于是将指令集设计得更强大、更灵活,并且那个时期的存储器既昂贵且速度慢,因此指令使用了变长编码,以节约存储空间,由于一条指令就能完成很多功能,从而减少了对内存的访问次数,这样也减少了缓慢的存储器访问对程序性能的影响。典型的CISC指令集架构就是Intel的x86 ISA。上世纪70年代中期,人们发现CISC 指令集中的各种指令,其使用频率相差悬殊,大约有20%的指令会被反复使用,占整个程序代码的80%。而余下80%的指令却不经常使用,只占整个程序代码的20%,显然,这种结构是不太合理的。于是人们提出将指令集和处理器进行重新设计,减少那些使用不多的指令,只保留常用的简单指令,这样处理器就不需要浪费太多的晶体管去做那些很复杂又很少使用的功能,于是产生了RISC。1979
年美国加州大学伯克利分校的David Pattern首先提出了RISC的概念,RISC 并不只是简单地减少指令,更主要的目的是研究如何使计算机的结构更加简单合理以提高运算速度。其特点是指令长度固定、指令格式种类少、寻址方式种类少、大量使用寄存器等。由于在RISC中使用的指令大多数是简单指令且都能在一个时钟周期内完成,因而处理器的频率得以大幅提升,同时易于设计流水线。RISC是计算机历史上的一个里程碑,以致有人开玩笑的把RISC定义为:1985年之后发布的所有处理器。
Intel也尝试做RISC处理器,但是因为兼容性问题,没有成功,后来在1995年,Intel的David B.Papworth和他的同事一起设计了Pentium Pro处理器,在这个处理器中,x86指令先被解码为类似于RISC指令的微操作(microoperation,简称为uops),之后的执行过程采用RISC内核,这种方式一直延续至今。
1.2.2 主要的几种ISA
目前并没有一种统一的ISA为各个处理器厂商所接受,而是存在多种ISA,就像这个世界存在多种语言一样,但是主要的语言只有几种:汉语、英语、法语、俄语等。主要的ISA也只有几种:x86、ARM、SPARC、POWER、MIPS,除了x86是CISC ISA外,其余都是RISC ISA。
1、x86
x86架构于1978年推出的Intel 8086处理器中首度出现,三年后,Intel 8086为IBM PC所选用,之后x86便成为了个人计算机的标准平台,成为了历史上最成功的指令集架构。目前绝大多数个人计算机使用的都是兼容x86指令集架构的处理器。
2、ARM
1985年,英国的Acorn公司设计了自己的第一代32位、6MHz处理器,命名为Acorn RISC Machine,简称为ARM1。1990年,由苹果公司、VLSI公司共同出资,改组Acorn为ARM计算机公司,同时不再涉足具体芯片生产,只出售IP核。ARM公司设计低功耗、高性能的CPU内核,然后授权给其他公司,后者设计生产具体的处理器芯片。ARM侧重于低功耗、低成本,主要面向的是嵌入式应用,随着智能手机、平板等移动设备的普及,ARM发展的非常迅速。
ARM架构从v4、v4T、v5、v5E、v6,发展到v7,其中v7又分为v7-A、v7-R、v7-M等多种,苹果公司的A9处理器采用的就是ARM v7-A架构。
3、SPARC
SPARC(Scalable Processor ARChitecture,可扩展处理器架构)源自伯克利分校上世纪80年代的研究,由Sun公司在1985年首先提出。1989年成为商用架构,生产出SPARC系列的处理器,Sun将其用在高性能工作站和服务器上。SPARC架构目前的版本有v8、v9。
SPARC架构对外完全开放,在此基础上出现了一些开放源代码的处理器,比如:Sun公司的UltraSPARC T1、LEON等。其中,LEON是一种SPARC v8架构的处理器,至今已发布到了LEON4。最初的LEON1与LEON2由欧洲航天局发布,LEON3由Gaisler Research公司设计发布,2008年Aeroflex收购了Gaisler Research公司,并于2010年1月发布了LEON4,不过LEON4至今还没有公布源代码。LEON系列使用VHDL编写代码,原计划是使用在航天器上。
4、POWER
POWER(Performance Optimization With Enhanced RISC)是由IBM公司设计开发的一种RISC结构的指令集架构。IBM生产的很多服务器、大型机、小型机及工作站都采用POWER架构的微处理器作为其主CPU使用。
1991年成立了AIM联盟(AIM为Apple、IBM、Motorola的首字母),对POWER架构进行了修改,形成了PowerPC架构。2004年IBM发起了Power.org联盟,发布了统一的指令集架构,将POWER与PowerPC统一到新的Power架构中。
5、MIPS
MIPS的含义是无内锁流水线微处理器(Microprocessor without Interlocked Piped Stages),是上世纪80年代诞生的RISC CPU的重要代表,其设计者John Hennessy时任斯坦福大学的教授。当初的设计基于以下理念:使用相对简单的指令,结合优秀的编译器以及采用流水线执行指令的硬件,就可以用更少的晶元面积生产更快的处理器。这一理念是如此的成功,以至于1984年就成立了MIPS计算机系统公司对MIPS架构进行商业化。在随后的十几年中,MIPS架构在很多方面得到发展,在工作站和服务器系统中得到了很多应用。MIPS架构也从MIPS
I、MIPS II、MIPS III、MIPS IV、MIPS V、MIPS32发展到MIPS64。John Hennessy与RISC概念的提出者David Pattern合著了计算机领域影响甚广的教科书《计算机体系结构——量化研究方法》,该书至今已出到第五版。
国内的龙芯处理器采用的就是MIPS架构。本书计划实现的处理器也采用MIPS架构,这里涉及到两个问题。
(1)为什么要采用一个现有的指令集架构?
这是因为现有的指令集架构已经形成了一套完善的环境,其中既有成熟的编译器,还有大量的应用程序,采用现有的指令集架构,都可以直接使用这些环境。反之,如果设计自己独有的一套指令集架构,那么编译器、应用软件都需要自己重新开发,工作量巨大。还是以语言作比喻,一个人当然可以发明、使用自己独有的语言,但是如何与别人交流呢?无法与人交流,再优秀的语言也注定会消失。
(2)为什么要采用MIPS架构?
首先MIPS的设计是RISC架构中的经典之作,很多处理器都吸收了其中的设计思想,其次,MIPS架构中指令的专利期已过,可以自由使用。
本章接下来将重点介绍MIPS指令集架构。
明天继续!
自己动手写处理器之第一阶段(1)——计算机的简单模型、架构、指令集