一、体系结构基础知识
1、什么是计算机体系结构
计算机体系结构是从传统机器级语言程序员的角度所看到的系统的属性,是概念上的结构和功能上的行为。本课程的主线就是在amdahl定律的指导下通过指令系统对数据进行处理、存储和传输。
传统机器级语言程序员所看到的主要属性是该机器指令集的功能特性,而高级语言程序员看到的主要属性是该机器配置的高级语言的功能特性
计算机体系结构的基础:
理论基础:图灵机
结构基础:冯诺依曼结构
物质基础:摩尔定律
2、计算机系统的层次
3、体系结构和组成和实现的关系
具有相同系统结构的计算机可以采用不同的组成,一种计算机组成可以采用多种不同的计算机实现。
4、计算机系统结构的分类
(1)冯氏分类法
(2)Flynn分类法
Flynn分类法,是基于指令流和数据流的数量对计算机进行分类的方法。
一系列修改那些流经数据处理单元的数据(数据流)的命令,可以被认为是一个指令流。
- 单指令流单数据流(SISD)——传统的计算机包含单个CPU,它从存储在内存中的程序那里获得指令,并作用于单一的数据流(本例中就是一个指令处理一条数据)。
- 单指令流多数据流(SIMD)——单个的指令流作用于多于一个的数据流上。例如有数据4、5和3、2,一个单指令执行两个独立的加法运算:4+5和3+2,就被称为单指令流多数据流。SIMD的一个例子就是一个数组或向量处理系统,它可以对不同的数据并行执行相同的操作。
- 多指令流单数据流(MISD)——用多个指令作用于单个数据流的情况实际上很少见。这种冗余多用于容错系统。
- 多指令流多数据流(MIMD)——这种系统类似于多个SISD系统。实际上,MIMD系统的一个常见例子是多处理器计算机,如Sun的企业级服务器。
5、定量分析技术
(1)以经常性事件为重点
经常性事件就是经常发生的事件,这类事件往往占用时间较多,设计的时候往往要提高这类事件的处理效率,从而缩短时间
蓝色部分为经常型时间,很明显加快经常性事件带来的效率提升更高
(2)Amdahl定律
推导过程:
本质上,该定律就是求比原来快了多少倍,其中加入Fe的时间占比作为变量,这样就能够便于数学分析
通过数学分析,我们发现,①找到占比最大的经常性事件Fe②提高该事件的加速比Se是提高总效率的两个因素,只顾其一是不行的,需要统筹兼顾,但是现实中,一般提高Fe的效果要好些
实际上①②都是在缩短Fe蓝色条
(3)CPU性能公式
CPU时间:一个程序在 CPU 上运行的时间。(不包括I/O时间)
主频、时钟频率:CPU 内部主时钟的频率,表示1秒可以完成多少个周期。
时钟周期 = 1 / 频率
指令周期:取出并执行一条指令的时间;
CPI:平均每条指令耗费的时钟周期数,CPI = 执行程序所需的时钟周期数 / 所执行的指令条数
我们约定 IC :程序所执行的指令条数
所以CPU时间 = CPI * IC * 时钟周期时间=(IC*CPI ) / 频率
(4)局部性原理
转自:局部性原理
局部性通常有两种不同的形式:时间局部性和空间局部性。
①时间局部性
在一个具有良好的时间局部性的程序中,被访问过一次的存储器位置很可能在不远的将来会被再次访问。
②空间局部性
在一个具有良好空间局部性的程序中,如果一个存储器位置被访问了一次,那么程序很可能在不远的将来访问附近的一个存储器位置。
③局部性原理的应用
局部性原理对硬件和软件的设计都有着极大的影响,从硬件到操作系统、再到应用程序,它们的设计都用到了局部性原理。
正是由于局部性原理的存在,在硬件层通过引入高速缓存存储器能够在很大程度上提升程序运行的速度。操作系统的虚拟地址空间的技术,以及缓存磁盘文件系统中最近被使用的磁盘块等都用到了局部性原理。在应用程序设计中应用到的缓存思想。
④局部性简单原则
- 重复引用同一个变量的程序有良好的时间局部性。
- 做顺序访问的程序具有良好的空间局部性。
- 循环结构具有良好的空间局部性和时间局部性。循环体越小,循环迭代次数越多,局部性越好。
6、并行性发展
(1)定义
在同一时间或同一时间间隔完成两种或两种以上工作
同时性:指两个或两个以上事件在同一时刻发生。
并发性:指两个或两个以上事件在同一时间间隔发生。
(2)从处理数据的角度看
并行性等级从低到高可分为:
- 字串位串:同时只对一个字的一位进行处理。这是最基本的串处理方式,不存在并行性。
- 字串位并:同时对一个字的全部位进行处理,不同字之间是串行的。这里已开始出现并行性。
- 字并位串:同时对许多字的一位进行处理。这种方式有较高的并行性。
- 全并行:同时对许多字的全部位进行处理。这是最高一级的并行性。
(3)从执行程序的角度看
并行性等级从低到高可分为:
指令内部并行:一条指令执行时各微操作之间并行。
指令级并行:并行执行两条或多条指令。
线程级并行:并行两个或两个以上的线程,通常是一个进程内控制派生的多个线程为调度单位
任务级或过程级并行:并行执行两个以上过程或任务(程序段)。
作业或程序级并行:并行执行两个以上作业或程序。
(4)提高并行性的方法
(1)时间重叠。在并行性概念中引入时间因素,即多个处理过程在时间上相互错开,轮流重叠地使用同一套硬件设备的各个部分,以加快硬件周转时间而赢得速度。
例如:流水线技术
(2)资源重复。在并行性概念中引入空间因素,以数量取胜的原则,通过重复设置硬件资源,大幅度提髙计算机系统的性能。随着硬件价格的降低,这种方式在单处理机中广泛使用,而多处理机本身就是实施“资源重复”原理的结果。因此资源重复可称为空间并行技术。
例如:加入多个加法器、乘法器,多体存储器,阵列处理机等
(3)资源共享。这是一种软件方法,它使多个任务按一定时间顺序轮流使用同一套硬件设备。例如多道程序、分时系统就是遵循“资源共享”原理而产生的,资源共享既降低了成本,又提高了计算机设备的利用率。上述三种并行性反映了计算机系统结构向高性能发展的自然趋势:一方面在单处理机内部广泛运用多种并行性措施,另一方面发展各种多计算机系统。
例如:分时操作系统
二、计算机指令集结构
1、指令集结构的各种分类方法
区别不同指令集结构的主要因素: CPU中用来存储操作数的存储单元的类型
CPU中用来存储操作数的存储单元的主要类型有:
- 堆栈结构
- 累加器结构
- 通用寄存器组
- 根据操作数的来源不同,又可进一步分为:
- 寄存器-存储器结构(RM结构)
- 寄存器-寄存器结构(RR结构) 也称为load-store结构,这个名称强调:只有load指令和store指令能够访问存储器。
对于不同类型的指令集结构,操作数的位置、个数以及操作数的给出方式(显式或隐式)也会不同。
- 显式给出:用指令字中的操作数字段给出
- 隐式给出:使用事先约定好的存储单元
灰色块:操作数 黑色块:结果 TOS(Top Of Stack):栈顶
现代指令集结构的主流:通用寄存器结构
在灵活性和提高性能方面有明显的优势。跟其他的CPU内部存储单元一样,寄存器的访问速度比存储器快。
对编译器而言,能更加容易、有效地分配和使用寄存器,有效地利用寄存器来计算表达式的值。 针对(AB)-(CD)-(E*F)乘法运算任意次序,但堆栈不可以。寄存器可以用来存放变量。
(1)减少对存储器的访问,加快程序的执行速度;
(因为寄存器比存储器快)
(2)用更少的地址位(相对于存储器地址来说)来对寄存器进行寻址,从而有效地减少程序的目标代码的大小。
2、寻址方式
采用多种寻址方式可以显著地减少程序的指令条数,但可能增加计算机的实现复杂度以及指令的CPI。
立即数寻址方式和偏移寻址方式的使用频度最高。
程序所使用的偏移量大小分布十分广泛主要是因为在存储器中所保存的数据并不是十分集中,需要使用不同的偏移量才能对其进行访问。 较小的偏移量和较大的偏移量均占有相当大的比例
最常用的是较小的立即数;有时也会用到较大的立即数(主要是用于地址计算)。在指令集结构设计中,至少要将立即数的大小设置为8~16位。
3、指令集结构的功能设计
指令集结构的功能设计是确定软、硬件功能分配,即确定哪些基本功能应该由硬件实现,哪些功能由软件实现比较合适。在确定哪些基本功能用硬件来实现时,主要考虑3个因素:速度、成本、灵活性
硬件实现的特点: 速度快、成本高、灵活性差
软件实现的特点:速度慢、价格便宜、灵活性好
*对指令集的基本要求:完整性、规整性、高效率、兼容性 *
完整性:在一个有限可用的存储空间内,对于任何可解的问题,编制计算程序时,指令集所提供的指令足够用。
规整性:主要包括对称性和均匀性。对称性:所有与指令集有关的存储单元的使用、操作码的设置等都是对称的。均匀性:指对于各种不同的操作数类型、字长、操作种类和数据存储单元,指令的设置都要同等对待。
- 例如:在存储单元的使用上,所有通用寄存器都要同等对待。在操作码的设置上,如果设置了A-B的指令,就应该也设置B-A的指令。
- 例如:如果某机器有5种数据表示,4种字长,两种存储单元,则要设置5×4×2=40种同一操作的指令。
高效率:指指令的执行速度快、使用频度高。
兼容性
在设计指令集结构时,有两种截然不同的设计策略CISC和RISC
(1)CISC(Complex Instruction Set Computer复杂指令集计算机)
增强指令功能,把越来越多的功能交由硬件来实现,并且指令的数量也是越来越多。强化指令功能,减少程序的指令条数,以达到提高性能的目的。
增强指令功能主要是从以下几个方面着手:①面向目标程序增强指令功能②面向高级语言的优化实现来改进指令集③面向操作系统的优化实现改进指令集
①面向目标程序增强指令功能
目标:(1)缩短程序的长度,即减少程序的空间开销
(2)缩短程序的执行时间,即减少程序的时间开销
途径:
增强运算型指令的功能
增强数据传送指令的功能
增强程序控制指令的功能
②面向高级语言的优化实现来改进指令集
缩小高级语言与机器语言的语义差距。 高级语言与一般的机器语言的语义差距非常大,为高级语言程序的编译带来了一些问题。(1)编译器本身比较复杂。(2)编译生成的目标代码比较难以达到很好的优化。
上图即改进的各种方式
增强对高级语言和编译器的支持 1、对源程序中各种高级语言语句的使用频度进行统计与分析,对使用频度高、执行时间长的语句,增强有关指令的功能,加快这些指令的执行速度,或者增加专门的指令,可以达到减少目标程序的执行时间和减少目标程序长度的目的。2、增强系统结构的规整性,减少系统结构中的各种例外情况。3、间接执行高级语言机器:高级语言成为机器的汇编语言,这时高级语言和机器语言是一一对应的。用汇编的方法把高级语言源程序翻译成机器语言程序。4、直接执行高级语言的机器:直接把高级语言作为机器语言,直接由固件/硬件对高级语言源程序的语句逐条进行解释执行。这时既不用编译,也不用汇编。
③面向操作系统的优化实现改进指令集
缩短操作系统与计算机系统结构之间的语义差距,减少运行操作系统的时间和节省操作系统软件所占用的存储空间。改进途径:(1)通过统计操作系统中的指令和指令串的使用频度来改进(2)增设专用于操作系统的新指令
(2)RISC(Reduced Instruction Set Computer精简指令集计算机)
尽可能地把指令集简化,不仅指令的条数少,而且指令的功能也比较简单。
CISC带来的问题:指令集庞大,指令条数很多,许多指令的功能又 很复杂,使得控制器硬件非常复杂。占用了大量的芯片面积(如占用CPU芯片总面积的一半以上),给VLSI设计造成很大的困难;增加了研制时间和成本,容易造成设计错误。
RISC设计原则:
指令条数少而简单。只选取使用频度很高的指令,在此基础上补充一些最有用的指令。
采用简单而又统一的指令格式,并减少寻址方式;指令字长都为32位或64位。
指令的执行在单个机器周期内完成。(采用流水线机制)
采用load-store结构。只有load和store指令才能访问存储器,其他指令的操作都是在寄存器之间进行。
大多数指令都采用硬连逻辑来实现。
强调优化编译器的作用,为高级语言程序生成优化的代码。
充分利用流水技术来提高性能。
控制指令:
控制指令是用来改变控制流的。
- 跳转:当指令是无条件改变控制流时,称之为跳转指令。
- 分支:当控制指令是有条件改变控制流时,则称之为分支指令。
常用的3种表示分支条件的方法及其优缺点 :
转移目标地址的表示最常用的方法:在指令中提供一个偏移量,由该偏移量和程序计数器(PC)的值相加而得出目标地址。
过程调用和返回:除了要改变控制流之外,可能还要保存机器状态,至少也得保存返回地址(放在专用的链接寄存器或堆栈中)。过去有些指令集结构提供了专门的保存机制来保存许多寄存器的内容。现在较新的指令集结构则要求由编译器生成load和store指令来保存或恢复寄存器的内容。
4、操作数的类型和大小
数据表示:计算机硬件能够直接识别、指令集可以直接调用的数据类型。
所有数据类型中最常用、相对比较简单、用硬件实现比较容易的几种。
数据结构:由软件进行处理和实现的各种数据类型。
研究:这些数据类型的逻辑结构与物理结构之间的关系,并给出相应的算法。
表示操作数类型的方法有两种:
- 由指令中的操作码指定操作数的类型。
- 带标志符的数据表示。给数据加上标识,由数据本身给出操作数类型。(由于需要在执行过程中动态检测标志符,动态开销比较大,所以采用这种方案的机器很少见。)
操作数的大小:操作数的位数或字节数。
主要的大小:字节(8位)、半字(16位)、字(32位)、双字(64位)
5、指令格式的设计
如何设计合适的指令格式,适用于体系结构设计。
由于指令由两部分组成:操作码、地址码,所以主要的设计方法为确定指令字的编码方式,包括操作码字段和地址码字段的编码和表示方式。
操作码的编码比较简单和直观:
- Huffman编码法:减少操作码的平均位数,但所获得的编码是变长的,不规整,不利于硬件处理。
- 固定长度的操作码:保证操作码的译码速度。
两种表示寻址方式的方法:
- 将寻址方式编码于操作码中,由操作码描述相应操作的寻址方式。适合:处理机采用load-store结构,寻址方式只有很少几种。
- 设置专门的地址描述符,由地址描述符表示相应操作数的寻址方式。 适合:处理机具有多种寻址方式,且指令有多个操作数。
设计考虑因素:
1、机器中寄存器的个数和寻址方式的数目对指令平均字长的影响以及它们对目标代码大小的影响。
2、所设计的指令格式便于硬件处理,特别是流水实现。
3、指令字长应该是字节(8位)的整数倍,而不能是随意的位数。
指令集的3种编码格式:变长编码格式、定长编码格式、混合型编码格式
6、MIPS指令集
介绍MIPS64的一个子集,简称为MIPS。
(1)MIPS的寄存器
1、32个64位通用寄存器(GPRs)
- R0,R1,…,R31
- 也被称为整数寄存器
- R0的值永远是0
2、32个64位浮点数寄存器(FPRs)
- F0,F1,…,F31
用来存放32个单精度浮点数(32位),也可以用来存放32个双精度浮点数(64位)。存储单精度浮点数(32位)时,只用到FPR的一半,其另一半没用。
3、一些特殊寄存器
- 它们可以与通用寄存器交换数据。例如,浮点状态寄存器用来保存有关浮点操作结果的信息。
(2)MIPS的数据表示
1、MIPS的数据表示
- 整数:字节(8位)、半字(16位)、字(32位)、双字(64位)
- 浮点数:单精度浮点数(32位) 双精度浮点数(64位)
2、字节、半字或者字在装入64位寄存器时,用零扩展或者用符号位扩展来填充该寄存器的剩余部分。装入以后,对它们将按照64位整数的方式进行运算。
(3)MIPS的数据寻址方式
1、立即数寻址与偏移量寻址(立即数字段和偏移量字段都是16位的。)
2、寄存器间接寻址是通过把0作为偏移量来实现的
3、16位绝对寻址是通过把R0(其值永远为0)作为基址寄存器来完成的
4、MIPS的存储器是按字节寻址的,地址为64位
5、所有存储器访问都必须是边界对齐的
(4)MIPS的指令格式
寻址方式编码到操作码中、所有的指令都是32位的、操作码占6位、3种指令格式
①I类指令
包括所有的load和store指令、立即数指令、分支指令、寄存器跳转指令、寄存器链接跳转指令。
立即数字段为16位,用于提供立即数或偏移量。
②R类指令
包括ALU指令、专用寄存器读/写指令、move指令等。
③J类指令
包括跳转指令、跳转并链接指令、自陷指令、异常返回指令。在这类指令中,指令字的低26位是偏移量,它与PC值相加形成跳转的地址。
(5) MIPS的操作
MIPS指令可以分为四大类:load和store、ALU操作、分支与跳转、浮点操作
符号的意义:
下标:表示字段中具体的位
- 例如:Regs[R4]0:寄存器R4的符号位、Regs[R4]56..63:R4的最低字节
Mem:表示主存
上标:用于表示对字段进行复制的次数。
- 例如:0 32:一个32位长的全0字段
符号##:用于两个字段的拼接,并且可以出现在数据传送的任何一边。
(6)MIPS的控制指令
由一组跳转和一组分支指令来实现控制流的改变
①跳转指令
根据跳转指令确定目标地址的方式不同以及跳转时是否链接,可以把跳转指令分成4种。
确定目标地址的方式:
把指令中的26位偏移量左移2位(因为指令字长都是4个字节)后,替换程序计数器的低28位。
间接跳转:由指令中指定的一个寄存器来给出转移目标地址。
跳转的两种类型:
- 简单跳转:把目标地址送入程序计数器。
- 跳转并链接:把目标地址送入程序计数器,把返回地址(即顺序下一条指令的地址)放入寄存器R31。
②分支指令(条件转移)
分支条件由指令确定。例如:测试某个寄存器的值是否为零
提供一组比较指令,用于比较两个寄存器的值。例如:“置小于”指令
有的分支指令可以直接判断寄存器内容是否为负,或者比较两个寄存器是否相等。
分支的目标地址。由16位带符号偏移量左移两位后和PC相加的结果来决定
一条浮点条件分支指令:通过测试浮点状态寄存器来决定是否进行分支。
(7)MIPS的浮点操作
由操作码指出操作数是单精度(SP)或双精度(DP),包括加、减、乘、除,分别有单精度和双精度指令。
- 后缀S:表示操作数是单精度浮点数
- 后缀D:表示是双精度浮点数
浮点数比较指令:根据比较结果设置浮点状态寄存器中的某一位,以便于后面的分支指令BC1T(若真则分支)或BC1F(若假则分支)测试该位,以决定是否进行分支。