研distance——计算机组成部分
概论
历史: 电子管->晶体管->集成电路 比较成熟的集成电路出现于1972
冯诺依曼机:
- 采用“存储程序”的工作方式。程序和原始数据送入主存后才能执行,计算机自动逐条执行指令,直至执行结束
- 计算机硬件系统由运算器、存储器、控制器、输入设备和输出设备5大部件组成。
- 存储器分为主存和辅存,对应现在的内存和硬盘,由存储单元组成,存储单元可存储一串二进制代码,称这串代码为存储字,称这串代码的位数为存储字长
- 主存由地址寄存器MAR和数据寄存器MDR以及时序控制逻辑组成,MAR用于寻址,其位数对应着存储单元的个数,存放访问地址,需要译码才能定位到存储单元,MDR的位数和存储字长相等,暂存要从存储器读写的信息,时序控制逻辑产生操作的时序信号
- 运算器的核心是算术逻辑单元ALU,运算器包含若干通用寄存器,用于暂存操作数和中间结果,程序状态寄存器(PSW),也称标志寄存器用于存放运算中的一些状态信息
- 控制器由程序计数器(PC)、指令寄存器(IR)和控制单元(CU)组成
- PC用来存放当前欲执行指令的地址,可以自增1来寻址到下一个指令
- IR用来存放当前的指令,其内容来自主存的MDR,指令中操作码送到CU,地址码送至MAR
- CU通过操作码产生需要的命令序列
- 指令和数据以同等地位存储在存储器中,形式上没有区别,CPU用指令周期的不同阶段区分他们
- 指令和数据均用二进制代码表示。指令由操作码和地址码组成,操作码指出操作的类型,地址码指出操作数的地址

运算器和控制器集成到同一个芯片上,称为中央处理器(CPU)。CPU和主存储器共同构成主机。其他设备 称为外部设备
软件按其功能分类,可分为系统软件和应用软件。
语言可分为:
- 机器语言,二进制代码语言,计算机可以直接识别和执行的语言
- 汇编语言,用英文单词或其缩写代替二进制的指令代码,必须被汇编程序翻译为机器语言后,才可以执行
- 高级语言,现在使用的绝大部分编程语言,最后会被编译成汇编或者机器语言执行
翻译程序可分为:
- 汇编程序(汇编器)。将汇编语言程序翻译成机器语言程序。
- 解释程序(解释器)。将源程序中的语句按执行顺序逐条翻译成机器指令并立即执行。
- 编译程序(编译器)。将高级语言程序翻译成汇编语言或机器语言程序
对某一功能来说,既可以由硬件实现,又可以由软件实现,从用户的角度来看,它们在功能上是等价的。这一等价性被称为软、硬件逻辑功能的等价性。例如浮点数运算
没有配备软件的纯硬件系统称为裸机。第3层〜第5层称为虚拟机,上层依赖于下层
软件和硬件之间的界面就是指令集体系结构(ISA), ISA定义了一台计算机可以执行的所有指令的集合,ISA是软件能感知到的部分,也称软件可见部分
工作原理
- 根据PC取指令
- 指令译码,INC PC
- 取操作数,执行
- 送结果
- 预处理,例如头文件插入程序文件
- 编译阶段产生一个汇编程序,每条语句都对应一个机器语言指令
- 汇编阶段,翻译成机器语言指令(二进制)
- 将可重定位文件与标准库函数合并成可执行文件
执行过程(以取数指令为例)
- 取指令:PC->MAR->M->MDR->IR
根据PC取指令到IR。将PC的内容送MAR, MAR中的内容直接送地址线 ,同时控制器将读信号送读/写信号线,主存根据地址线上的地址和读信号,从指定存储单元读出指令,送到数据线上,MDR从数据线接收指令信息,并传送到IR中。
- 分析指令:OP(IR)->CU
指令译码并送出控制信号。控制器根据IR中指令的操作码,生成相应的控制信号,送到不同的执行部件。在本例中,IR中是取数指令,因此读控制信号被送到总线的控制线上。
- 执行指令:Ad(IR)->MAR->M->MDR->ACC
取数操作:将IR中指令的地址码送MAR, MAR中的内容送地址线,同时控制器将读信号送读/写信号线,从主存中读出操作数,并通过数据线送至MDR,再传送到ACC中。每取完一条指令,还须为取下条指令做准备,计算下条指令的地址,即(PC)+1 -> PC
- 冯•诺依曼机基本工作方式是控制流驱动方式
- IR存放当前执行的指令代码,PC存放下一条指令的地址
- 地址译码器是主存的构成部分,不属于CPU(但一般现代cpu也集成)
- 速度上:寄存器>Cache > 内存
- n位计算机表明计算机字长,与地址位数无关
- 由高级语言转化为汇编语言的过程称为编译,把汇编语言源程序翻译成机器语言程序的过程称为汇编
- 相联存储器既可以按地址寻址又可以按内容(通常是某些字段)寻址
- CPU可以根据指令周期的不同阶段来区分是指令还是数据,通常在取指阶段取出的是指令,在执行阶段取出的是数据
性能指标
- 字长:计算机进行一次整数运算(即定点整数运算)所能处理的二进制数据的位数,一般等于寄存器大小,且是字节的整数倍
- 数据通路带宽:数据总线一次能并行传送信息的位数(不是cpu内部的数据总线)
- 主存容量:主存容量是指主存储器所能存储信息的最大容量,通常以字节来衡量,也可用字数x字长(如
512K*16位
)来表示存储容量。其中,MAR的位数反映了存储单元的个数,MDR的位数反映了存储单元的字长
- 吞吐量:指系统在单位时间内处理请求的数量,主要取决于主存的存取周期
- 响应时间:从用户向计算机发送一个请求,到系统对该请求做出响应并获得所需结果的等待时间。通常包括CPU时间与等待时间。操作系统有相同概念
- CPU时钟周期:通常为节拍脉冲或T周期,即主频的倒数,它是CPU中最小的时间单位
- 主频(CPU时钟频率):机器内部主时钟的频率
- CPI (Cycle Per Instruction):执行一条指令所需的时钟周期数,对一个程序来说,指的是平均值
- CPU执行时间:运行一个程序所花费的时间,即\(cpu时间周期数/主频=(指令条数*CPI)/主频\)
- MIPS (Million Instructions Per Second):即每秒执行多少百万条指令:
\[ MIPS =指令条数/(执行时间*10^6)=主频/(CPI*10^6) \]
- 1ms 1毫秒=0.001秒=10-3秒
- 1μs 1微秒=0.000001=10-6秒
- 1ns 1纳秒=0.0000000001秒=10-9秒
- 1ps 1皮秒=0.0000000000001秒=10-12秒
- 基准程序(Benchmarks):是专门用来进行性能评价的一组程序,对于不同的应用场合,应该选择不同的基准程序。
- 固件:将程序固化在ROM中组成的部件称为固件
- 存储字长等于MDR的位数,数据字长是数据总线一次能并行传送信息的位数,机器字长是CPU内部用于整数运算的数据通路的宽度,指令字长是一个指令字中包含的二进制代码的位数,且指令字长一般是存储字长整数倍
- 指令集更类似一个接口集合,或者说结构,相同指令不代表实现相同,接口是体系结构,实现则是计组
- cpu的指令寄存器对用户是完全透明的
- 计算机“运算速度”指标的含义是每秒能执行多少条指令
- cpu速度提高是通过提高频率实现的,也就是增加50%的cpu时间,相当于原来的时间除以1.5
- 机器字长一定等于CPU内部用于整数运算的运算器位数和通用寄存器宽度
- 全面代表计算机性能的是实际软件的运行情况
- 向后兼容是指时间上向后兼容,即新机器兼容使用以前机器的指令系统
数据
数制与编码
计算机使用二进制的原因:非1即0,在物理上容易区分,可以方便地转换成逻辑值,运算规则简单
r进制数可以表示为:
\[ K_{n}r^{n}+K_{n-1}r^{n-1}+\cdots+K_{0}r^{0}+K_{-1}r^{-1}+\cdots+K_{-m}r^{-m}=\sum_{i=n}^{-m}K_{i}r^{i} \]
转换时高位补0,有倍数关系的进制可以若干位转换对应一位,否则一般使用基数乘除法
对小数的进制转换,只需要分别对小数点前后的数字部分进行转换,然后拼接起来 ,但因为小数是离散的,所以不一定可以完全转化
符号“数字化”的数称为机器数,例如0表正, 1表负
十位数字的4位二进制码叫BCD码
根据小数点的位置是否固定,在计算机中有两种数据格式:定点表示和浮点表示,通常用定点补码整数表示整数,用定点原码小数表示浮点数的尾数部分,用移码表示浮点数的阶码部分,
定点数编码表示法主要有4种:原码、补码、反码和移码
- 原码 首位是符号位,其他位与数值相等,不足字长的补零,小数尾部补零,整数头部补零,字长n+1时,小数表示范围是:
\({\mathrm{-}}(1-2^{-n})\leqslant x\leqslant1-2^{-n}\)
整数范围是:
\(-(2^{n}-1)\leqslant x\leqslant2^{n}-1\)
原码简单直观,但0的表示不唯一,且运算较复杂
- 补码 正数的补码是他自己
负小数的补码是其与+2的和,小数表示范围为:
\(-1\leqslant x\leqslant1-2^{-n}\)
若字长是n+1负整数的补码相当于其与 \(2^{(n+1)}\) 的和,表示范围是
\(-2^{n}\leqslant x\leqslant2^{n}-1\)
优点:零的补码唯一,相比原码可以多表示一个-2^n,补码运算规则比较简单,且符号位可以和数值位一起参加运算
- 变形补码,又称模4补码,双符号位00表示正,11表示负,类似补码,区别只是负数加的是4
- 真值转换为补码:正数与原码一直,负数符号位取1,其他位由原码取反并加一得到
- 补码转换成真值:正数与原码一致,负数符号取负,其他位取反并加一
- 反码,正数与原码一致,负数符号位不变,其他取反
- 移码,在真值上加上一个常数(偏置值),通常这个常数取2^n
- 移码中零的表示唯一,都是2^n
- 一个真值的移码和补码仅差一个符号位,符号位取反就能相互转化
- 移码全0时,对应真值的最小值\(-2^n\),移码全1时,对应真值的最大值\(2^n-1\)。
- 移码可以反映数据原有的大小顺序
无符号整数默认为正数,由于不需要符号位,表示的最大数更大 \(2^{n+1}-1\)
- 二进制小数可以用十进制表示,反过来不行,因为相对于十进制,二进制小数是离散的
- x补所有位取反加一就会得到(-x)补
- N位的二进制小数可以表示的数的个数为 \(2^n\) 而十进制小数能表示的数的个数为 \(10^n\) ,意味着占比 \({0.2}^n\) 的十进制小数可以用二进制精确表示
- 对负数的补码来说,数值部分越大,真值的绝对值越小,真值越大
- H结尾一般表示16进制数
- 移码与补码表示的最小值绝对值比最大值绝对值大一,真值取反可能溢出
- 补码的符号位可以和数值部分一起参加运算
定点数值的运算
基本部件
一位全加器FA
和表达式:\(S_{i}=A_{i}\oplus B_{i}\oplus C_{i-1}\)
进位表达式:\(C_{i}=A_{i}B_{i}+(A_{i}\oplus B_{i})C_{i-1}\)串行进位加法器 把n个全加器相连可得到几位加法器,称为串行进位加法器,由于位数有限,高位自动丢失,所以实际是模2^n的加法运算
串行运算的效率会依赖于位数并行进位加法器 \[G_{i}=A_{i}B_{i},\;\;P_{i}=A_{i}\oplus B_{i},\]
\[C_{i}=G_{i}+P_{i}C_{i-1}\;\;\]
称为\(A_iB_i\)为进位产生函数,称\(A_{i}\oplus B_{i}\)为进位传递函数
G仅与Ai,Bi及最低进位C0有关,相互间的进位没有依赖关系
随着加法器位数的增加,Ci的逻辑表达式会变得越来越长,这会使电路结构变得很复杂,可以分组,组内先行进位,组间串行进位,甚至组内组间都并行,通常采用两级或多级先行进位加法器。
带标志加法器
ALU(算术逻辑单元) 能进行多种算术运算和逻辑运算,核心是带标志加法器,同时也能执行“与” “或”“非”等逻辑运算
其中A和B是两个n位操作数输入端,Cin是进位输入端,ALUop是操作控制端,用来决定ALU所执行的处理功能
移位运算
算术移位
码制 | 添补代码 | |
---|---|---|
正数 | 原码补码反码 | 0 |
负数 | 原码 | 0 |
负数 | 补码 | 左移添0,右移添1 |
负数 | 反码 | 1 |
三种机器数算术移位后的符号位均不变。
双符号位的最高符号位代表真正的符号,而低位符号位用于参与移位操作以判断是否发生溢出,如01表示结果正溢出,10表示结果负溢出
算术移位的情况下,补码左移不丢失精度的前提条件是其原最高有效位与原符号位要相同
逻辑移位 将操作数视为无符号数,逻辑左移时,高位移丢,低位添0;逻辑右移时,低位移丢,高位添0。
循环移位 分为带进位标志位CF的循环移位(大循环)和不带进位标志位的循环移位(小循环)
定点数的数学运算
定点数的实质是事先规定小数点位置,数据无需储存小数点,只关注具体运算
加减
- 补码 符号位与数值位一起参与运算:
\([A+B]_{\mathbb{补}}=[A]_{\mathbb{补}}+[B]_{\mathbb{补}}{\ \mathrm{(mod}\ 2^{n+1})}\)
\([A-B]_{\mathbb{补}}=[A]_{\mathbb{补}}+[-B]_{\mathbb{补}}{\ \mathrm{(mod}\ 2^{n+1})}\)
一个数真值的相反数的补码等于其补码所有位(包括符号位)取反并+1
其电路实现上,则相当于对Y和Y的取反进行一个选择,并对是否输入一个1进行选择,由一个sub控制端的0/1来决定,无符号整数的二进制表示相当于正整数的补码表示,因此,该电路同时也能实现无符号整数的加/减运算
OF(Overflow Flag)溢出标志,用于判断带符号数加减运算是否溢出。OF=1 溢出;OF=0 未溢出
\(\mathrm{OF}\equiv C_{\mathrm{n}}\oplus C_{\mathrm{n-1}}\)符号位进位与最高数位进位的异或
SF(Sign Flag)符号标志,用于判断带符号数加减运算结果的正负性。SF=1 结果为负;SF=0 结果为正
\(\mathrm{SF}=\mathrm{S}_{n}\)即运算结果最高位
ZF(Zero Flag)零标志,用于判断加减运算结果是否为0。ZF=1 表示结果为0;ZF=0 表示结果不为0
\(\mathrm{ZF}=\overline{S_{n}+\cdots+S_{2}+S_{1}}\)
CF(Carry Flag)进位/借位标志,用于判断无符号数加减运算是否溢出。CF=1 溢出;CF=0 未溢出。无符号加减法,加法溢出必有(最高位)进位,减法溢出必有(最高位)借位
\({\mathrm{CF}}=C_{\mathrm{out}}\oplus Sub\) (Cout表示进位输出,即最高位进位,Sub是低位加法器的进位输入,为0表示加法运算,为1表示减法,被减数除了符号位取反,同时则作为低位进位实现补码加1的效果)
这些标志信息通常会被送入 PSW 程序状态字寄存器或者标志寄存器FR(Flag Register)
溢出的判断
- 单符号位: 仅当两个符号相同的数相加或两个符号相异的数相减才可能产生溢出,例如正数之和符号位为1
无论是加法还是减法,只要参加操作的两个数符号相同,结果又与原操作数符号不同,则表示结果溢出。
设A的符号为As, B的符号为Bs,运算结果的符号为Ss,则溢出逻辑表达式为(0表示无溢出)
双符号位(模4补码): 运算结果的两个符号位Ss1Ss2相同,表示未溢出;运算结果的两个符号位不同,表示溢出
Ss1Ss2的结果:- 00,正数无溢出
- 01,正溢出
- 10,负溢出
- 11,负数无溢出
进位情况:
若符号位的进位Cs与最高数位的进位C1相同,则说明没有溢出,否则表示发生溢出。
CS为0时是上溢,相反是负溢,类似双符号位
溢出逻辑判断表达式为\(V=C_{s}\oplus C_{1},\),若V=0,表示无溢出;V=1,表示有溢出。
具体运算:
原码 加法:符号位相同的情况略,不同则用绝对值较大的减去较小的,取较大者的符号
减法:转换成A与-B的加法无符号整数
加法略,减法将减数所有位取反再加一与被减数相加得到结果
无符号数加法的溢出判断:最高位产生的进位=1时,发生溢出,否则未溢出。
无符号数减法的溢出判断:减法变加法,最高位产生的进位=0时,发生溢出,否则未溢出
乘除
- 乘法运算由累加和右移操作实现,可分为原码一位乘法和补码一位乘法。
- 原码一位乘法
无符号数乘法运算电路,从低到高进行加法,每加一次就逻辑右移
- 补码一位乘法(Booth算法)
x*y=-0.10001111
电路实现:每次从寄存器丫移出的最低位和它的前一位来决定是-[x]补、+[x]补还是+0
。
- 除法 分为原码除法和补码除法
符号拓展:把低位整数转换成高位整数,但符号与真值不变
正数的符号扩展非常简单,即符号位不变,新表示形式的所有扩展位都用0进行填充。
负数的符号扩展方法则根据机器数的不同而不同。原码表示负数的符号扩展方法与正数相同
补码表示负数的符号扩展方法:原有形式的符号位移动到新形式的符号位上,新表示形式的所有附加位都用1 (对于整数)或0(对于小数)进行填充。
原码除法运算(不恢复余数法)
补码除法运算(加减交替法)
\([x/y]_{补}=1.0101\,,\ \ 余\ 0.0111\times2^{-4}.\)
电路实现: 寄存器RQ分别存放被除数的高位低位,每次计算时同步左移
原码加减交替法最多加减N+2次(最后不够减要恢复余数),最后够减就是N+1次
补码加减交替法最多加减N+1次,商末尾恒置1
数据的存储与表示
- 同字长的类型,c语言中强制类型转换的结果保持位值不变,仅改变了解释这些位的方式,例如
short
和unsigned short
- 当大字长变量向小字长变量强制类型转换时,系统把多余的高位部分直接截断,低位直接赋值
- 短字长到长字长的转换时,不仅要使相应的位值相等,还要对高位部分进行扩展。如果原数字是无符号整数,则进行零扩展,扩展后的高位部分用0填充。否则进行符号扩展,扩展后的高位部分用原数字符号位填充。(char类型为8位无符号整数,其在转换为int时高位补0)
通常用最低有效字节(LSB)和最高有效字节(MSB)来分别表示数的低位和高位。例如,在32位计算机中,一个int型变量i的机器数为01 23 45 67H
,其最高有效字节MSB = 01H,最低有效字节LSB = 67H
现代计算机基本上都采用字节编址,即每个地址编号中存放1字节,多字节数据都存放在连续的字节序列中,排列方式可分为:
- 大端方式按从最高有效字节到最低有效字节的顺序存储数据,即最高有效字节存放在前面
- 小端方式按从最低有效字节到最高有效字节的顺序存储数据,即最低有效字节存放在前面
对于机器字长为32位的计算机,数据如果以边界对齐方式存放,半字地址一定是2的整数倍,字地址一定是4的整数倍
数据不按边界对齐时,节省空间,但会增加访问地址的次数与连接不同数据的计算量
- ALU是由组合逻辑电路构成的,最基本的部件是并行加法器
- 数据总线供ALU与外界交互数据使用,也是运算器部件
- 不带进位的循环左移将最高位进入最低位和标志寄存器C位
- 模4补码具有模2补码的全部优点且更易检查加减运算中的溢出问题
- 存储模4补码仅需一个符号位,因为任何一个正确的数值,模4补码的两个符号位总是相同的
- 采用双符号位时,第一符号位表示最终结果的符号,第二符号位表示运算结果是否溢出,可用一个异或判断
- 补码一位乘法中,最多需要n次移位,n+1次加法运算。原码乘法移位和加法运算最多均为n次
- 补码乘法右移n次,因此结果长度为2N
- 原码不恢复余数虽然名字如此,但最后一步不够减时需要恢复余数
- 做减法时,低位进位为Sub,即为1(Sub决定多路选择器是否将y的各位取反,也就是说补码的话之后还需要用多路复用器mux+1)
- c语言中short是半字,int是字,char是1B,在常见的32位计算机中,按边界对齐就是一个32位的字可以放两个short一个int四个char
- 乘法运算可以通过加法和移位来实现。编译器可以将乘法运算转换为一个循环代码段,在循环代码段中通过比较、加法和移位等指令实现乘法运算
- 阵列乘法器实现的乘法指令比使用ALU与位移器实现的快,只需要一个时钟周期
- 对无符号整数乘法,高n位都是0时,结果不会溢出
- ALU生成标志位时只负责计算,而不管运算对象是有符号数还是无符号数,CF= 1表示当作无符号数运算时溢出,OF= 1表示当作有符号数运算时溢出
浮点数的表示和运算
浮点数表示法是指以适当的形式将比例因子表示在数据中,让小数点的位置根据需要而浮动,一般表示为:\({\cal N}=(-1)^{S}\times M\times R^{E}\)
S取值0或1,用来决定浮点数的符号;M是一个二进制定点小数,称为尾数,一般用定点原码小数表示;E是一个二进制定点整数,称为阶码或指数,用移码表示。R是约定好的基数
阶码的值反映浮点数的小数点的实际位置;阶码的位数反映浮点数的表示范围;尾数的位数反映浮点数的精度。
浮点数的范围关于原点对称,超出范围会导致溢出,其中,下溢会被视为0
规格化操作
指通过调整一个非规格化浮点数的尾数和阶码的大小,使非零的浮点数在尾数的最高数位上保证是一个有效值
- 左规:当运算结果的尾数的最高数位不是有效位。左规时,尾数每左移一位、阶码减1 (基数为2时)。左规可能要进行多次
- 右规:当运算结果的尾数的有效位进到小数点前面时,需要进行右规。将尾数右移一位、阶码加1 (基数为2时)。需要右规时,只需进行一次。
规格化浮点数的尾数M的绝对值应该满足\(1/R\leqslant|M|\lt 1,\)对原码来说,其绝对值的上下界分别是\((1-2^{-n})\)和1/2
IEEE 754标准
- 短浮点数(单精度、float型)
- 长浮点数(双精度、double型)
- 临时浮点数
规格化的浮点数最高位总是1,因此可以隐去,短浮点数与长浮点数都采用隐藏尾数最高数位的方法,因此可多表示一位尾数
存储浮点数阶码之前,偏置值要先加到阶码真值上。
eg.规格化的短浮点数真值为:
\[(-1)^{S}\times1.M\times2^{E-127}\]
短浮点数E的取值为1〜254 (8位表示),M为23位,共32位
长浮点数E的取值为1〜2046 (11位表示),M为52位,共64位。
最值则分别在EM的同时最小与同时最大处取,分别是\(2^{-(偏置值-1)}\)与\(2^{E_{max}-偏置值}*(2-2^{-M})\)
IEEE 754格式的浮点数,阶码偏移量不是2^n,是固定值127与1023
阶码全0或全1时,有其特别的解释
与定点数区别:
- 相同字长时浮点数范围更大
- 相同字长时浮点数精度更低
- 浮点运算需要规格化,并运算阶码和尾码,更为复杂
- 定点数结果超出表示范围则溢出,浮点运算中,运算结果超出尾数表示范围却不一定溢出,只有规格化后阶码超出所能表示的范围时,才发生溢出。
浮点数的加减运算
- 对阶,使两个操作数的小数点位置对齐,阶码相等。将阶码小的尾数右移一位(基数为2),阶加1,直到两个数的阶码相等为止,过程可能舍弃有效位影响精度
- 尾数求和,尾数按定点数规则运算
- 对结果进行规格化(左规一次相当于乘2,右规一次相当于除2)
- 1.xxxx时,右规
- 0.0xx01xxxx时,左规
- 在对阶和尾数右规时,可能会对尾数进行右移,为保证运算精度,一般将低位移出位保留下来,参加中间过程的运算,最后将运算结果进行舍入
- 0舍1入法,舍入为最近的可表示数,正好中间时,则选择结果为偶数。这样可能会使尾数溢出,此时需再做一次右规
- 恒置1法,都把右移后的尾数末位恒置1。
- 截断法:直接截取所需位数,丢弃后面的所有位
- 溢出判断,在尾数规格化和尾数舍入时,可能会对阶码执行加/减运算。这时可能指数溢出
- 右规时数值很大的尾数舍入时,可能因为末位加1而发生尾数溢出,此时需要通过右规来调整尾数和阶,导致阶数加一,若右规后阶数全1则发生上溢
- 左规时类似前者,阶数全0则下溢
C语言中的float和double类型分别对应于IEEE 754单精度浮点数和双精度浮点数。long double类型对应于扩展双精度浮点数.
常见的类型转换中:
- char->int->long->double和float->double不会损失精度
- int转换为float时,虽然不会发生溢出,但float尾数连隐藏位共24位,当int型数的第24〜31位非0时,无法精确转换成24位浮点数的尾数,需进行舍入处理,影响精度。
- double->float可能损失精度或溢出
- float或double转换为int时,只保留整数部分,且可能溢出
用移码表示阶码的优点:
- 浮点数进行加减运算时要比较阶码的大小,移码比较大小更方便
- 检验移码的特殊值(0和max)时比较容易,0时相当于分母无穷大,表示负无穷大,max表示指数正无穷大,但若max时尾数不为0,则表示运算错误
浮点数舍入方法应该使误差尽可能对称,且高效
- 就近舍入,舍入为最近可表示的数
- 正向舍入,取右侧的数
- 负向舍入
- 截取,取绝对值小的数
关于基数
现假设尾数(含符号位)用4位2进制存储,则某以2为基数的浮点数规格化后为:0.101*2^(-1)
如果换乘以4为基数,规格化后就是:0.010(1)*4^0
由于基数更大,就需要更长的尾数表达一个数,因此尾数越大,前面没必要存的0就越多,这些对精度没有任何贡献的0占据的位置越多,精度就越低
基数不等于进制,基数越大精度越低,进制越大精度越高。本质上说基数与阶码相对,更大的基数会减少尾数的表达能力,但增加阶码即整个浮点数的表示范围
或者说,更大的基数,其阶码的变动就需要尾数更大幅度的变化,从而使表示的数变得稀疏
关于溢出的总结
- 阶码上溢出。一个正指数超过了最大允许值时,浮点数发生上溢出(即向∞方向溢出)。若结果是正数,则发生正上溢出(有的机器把值置为+∞);若结果是负数,则发生负上溢出(有的机器把值置为-∞)右规和尾数舍入都可能引起阶码上溢(尾数溢出时结果不一定溢出)
- 阶码下溢出。一个负指数比最小允许值还小时,浮点数发生下溢出。一般机器把下溢出时的值置为0 (+0或-0)。左规时可能引起阶码下溢
- 尾数溢出。当尾数最高有效位有进位时,发生尾数溢出。此时,进行“右规”操作:尾数右移一位,阶码加1,直到尾数不溢出为止。此时,只要阶码不发生上溢出,浮点数就不会溢出
- 非规格化尾数。当数值部分高位不是一个有效值时(如原码时为0或补码时与符号位相同),尾数为非规格化形式。此时,进行“左规”操作:尾数左移一位,阶码减1,直到尾数为规格化形式为止
- 对阶不会引起阶码上溢或下溢(阶码维持在与较大者一致)
- 可表示的数据个数取决于编码所采用的位数,编码位数一定,编码出来的数据个数就是一定的,浮点数和定点数没有不同(除非编码和值不是一一对应)
- 基数越大,范围越大,但精度变低(数变稀疏),运算中尾数右移的可能性越小,运算的精度损失越小,规格化更少,运算速度也更高
- 补码规格化的尾数,符号位与尾数最高位相反
- 对阶是将较小的阶码调整到与较大的阶码一致,因此不存在阶码减小、尾数左移的情况
- 采用规格化浮点数的目的主要是为了增加数据的表示精度
- 上下溢都是绝对值超出表示范围,和正负无关
IEEE 754
标准格式中,阶码全为0,尾数不全为0表示非规格化数,非规格化数可用于处理阶码下溢,上溢则只能报错(这种情况下尾数前不用补1,即实际数值为0.M,实际阶码固定为-126,用于表示绝对值极小的数)- 浮点数舍入的情况有两种:对阶、右规格化,定点数不需要舍入
- float保存24位整数,\(2^{24}\)以内的整数int可以无损转换
- 浮点数的加减运算,右规不会超过一次,左规不会超过n次
- 阶码上溢可能出现于运算完的右规或尾数舍入,下溢可能出现于运算完左规
存储器
概念
功能分类
- 主存,存放cpu计算需要的程序与数据可以和cache与辅存交换数据
- 辅助存储器,也就是外存,可以在寿命内长时间存放信息
- 高速缓冲存储器,cache,位于主存与cpu之间,通常和cpu集成
存取方式分类
- 随机存储器(RAM)
- 只读存储器(ROM),断电不会丢失数据
- 串行访问存储器,需按其物理位置的先后顺序寻址
- 顺序存取存储器,只能按某种顺序存取(磁带)
- 直接存取存储器,寻找到一定区域,在区域内顺序查找(磁盘,光盘)
可保存性分类
- 易失性存储器,如RAM
- 非易失性存储器,如ROM、磁表面存储器和光存储器
指标:
- 存储容量=存储字数X字长(1Byte=8bit)
- 单位成本:每位价格=总成本/总容量。
- 存储速度:数据传输率=数据的宽度/存取周期
- 存取时间(Ta):存取时间是指从启动一次存储器操作到完成该操作所经历的时间,分为读出时间和写入时间
- 存取周期(Tm):存取周期又称读写周期或访问周期。它是指存储器进行一次完整的读写操作所需的全部时间,也就是连续两次访问存储器之间所必需的最短时间间隔
- 主存带宽(Bm):主存带宽又称数据传输率,表示每秒从主存进出信息的最大数量(B/s)
在读写操作之后,总要有一段恢复内部状态的复原时间,因此一般存取周期大于存取时间
上一层的存储器一般作为低一层存储器的高速缓存,Cache-主存层和主存-辅存层中,上层内容是下一层的一部分
主存和Cache之间的数据调动是由硬件自动完成的,对所有程序员均是透明的
而主存和辅存之间的数据调动则是由硬件和操作系统共同完成的,对应用程序员是透明的。
- 存取时间是执行一次读操作或写操作的时间,分为读出时间和写入时间
- 存储周期是指存储器进行连续两次独立地读或写操作所需的最小时间间隔
- 1MB=\(2^{20}B\)
- 1s=\(10^3ms\)=\(10^6\)μs=\(10^9ns\)
- 速度排名:寄存器-Cache-主存-辅存
- 两个不同速度的存储器共同访问时,快者未命中时总访问时间是慢者时间,不同时访问则是两者时间之和
- Cache主存系统的效率=访问Cache的时间/平均访存时间
主存储器
主存储器由DRAM实现,靠处理器的那一层(Cache)则由SRAM实现,它们都属于易失性存储器,只要电源被切断,原来保存的信息便会丢失。DRAM的每位价格低于SRAM,速度也慢于SRAM
DRAM电容上的电荷一般只能维持1〜2ms,每隔一定时间必须刷新,通常取2ms,称为刷新周期。
- 集中刷新:指在一个刷新周期内,利用一段固定的时间,依次对存储器的所有行进行逐一再生,在此期间停止对存储器的读写操作,称为“死时间”,又称访存“死区”。
- 分散刷新:把对每行的刷新分散到各个工作周期中。增加了存取周期,但没有死区
- 异步刷新:具体做法是将刷新周期除以行数,得到两次刷新操作之间的时间间隔。利用逻辑电路每隔时间t产生一次刷新请求。减少刷新次数,也能避免死区过多
- 刷新对CPU是透明的,即刷新不依赖于外部的访问
- 动态RAM的刷新单位是行,由芯片内部自行生成行地址
- 刷新时不需要选片,即整个存储器中的所有芯片同时被刷新
存储器芯片由存储体、I/O读写电路、地址译码和控制电路等部分组成。
- 存储体(存储矩阵)。存储体是存储单元的集合,它由行选择线(X)和列选择线(Y)来选择所访问单元
- 地址译码器。用来将地址转换为译码输出线上的高电平,以便驱动相应的读写电路
- I/O控制电路。用以控制被选中的单元的读出或写入
- 片选控制信号,访问某个字必须选中且只选中其所在芯片,因此需要信号加以控制
- 读/写控制信号。根据CPU给出的读命令或写命令,控制被选中单元进行读或写
只读存储器(ROM) 结构更简单,存储密度更高,且更可靠
- 掩模式只读存储器MROM,制造时厂商写入,无法更改
- 一次可编程只读存储器PROM,可以用专门设备写入且只能写入一次
- 可擦除可编程只读存储器EPROM,可以多次写入,但次数有限,且写入时间较长
- flash存储器,不加电可以长期保存信息,也可以快速擦除重写,且价格较便宜,集成度高,存储元由MOS管组成,是一种半导体存储器,采用随机访问方式,可替代计算机外部存储器
- 固态硬盘SSD,长期保存信息、快速擦除与重写,读写速度快、低功耗
主存储器(Main Memory, MM)
- 记忆单元,储存一个个0/1,构成存储矩阵的基本单位
- 编制单位,有相同地址的存储元件构成的单位,一般按字节编址
指令访问主存的过程:
- cpu将地址送到MAR,并通过地址线将其送到主存的地址寄存器
- 与1.同时,将读写信号送到主存的读写控制电路(通过控制线)
- 执行指令,读写期间MDR用于存放具体数据
数据线的宽度与MDR的宽度相同,地址线的宽度与MAR的宽度相同,地址线位数会决定主存地址空间的寻址范围(从0开始索引)
DRAM通常采用地址引脚复用技术,行地址和列地址通过相同的引脚分先后两次输入
多模块存储器
多模块存储器是一种空间并行技术,利用多个结构完全相同的存储模块的并行工作来提高存储器的吞吐率。常用的有单体多字存储器和多体低位交叉存储器
- 单体多字系统,存储器中只有一个存储体,每个存储单元存储m个字,总线宽度也为m个字。一次并行读出m个字,地址必须顺序排列并处于同一存储单元。
- 一个存取周期中,从同一个地址取m条指令,依次送到cpu,每隔1/m存取周期,CPU向主存取一条指令,提高效率,但不适用于非连续的指令或数据
- 多体并行存储器,由多体模块组成。每个模块都有相同的容量和存取速度,各模块都有独立的读写控制电路、地址寄存器和数据寄存器。它们既能并行工作,又能交叉工作
- 高位交叉编址(顺序方式),高位地址表示体号,低位地址为体内地址。把低位的体内地址送到由高位体号确定的模块内进行译码,访问一个连续主存块时,总是先在一个模块内访问,等到该模块访问完才转到下一个模块访问,本质依旧是串行
- 低位交叉编址(交叉方式),低位地址为体号,高位地址为体内地址。每个模块按“模加”交叉编址,模块号=单元地址% m,可在不改变每个模块存取周期的前提下,采用流水线的方式并行存取,提高存储器的带宽
- 通俗易懂地理解:存取周期包括数据的传送和存储器的恢复,总线周期r是单纯读取数据的时间,因此所有要读的字存在不同模块时,读完一个模块就可以去下一个模块读,读完剩下的模块后,第一个模块已经恢复,这样就可以一直读下去
- 设模块字长等于数据总线宽度,模块存取一个字的存取周期为T,总线传送周期为r,为实现流水线方式存取,存储器交叉模块数应大于等于\(m=T/r\),m称为交叉存取度。每经过r时间延迟后启动下一个模块,交叉存储器要求其模块数必须大于等于m,以保证启动某模块后经过加
m*r
的时间后再次启动该模块时,其上次的存取操作已经完成(即流水线不间断)。 - 连续存取m个字所需的时间为\(t_{1}=T+(m-1)r\),远少于顺序读取时间mT
- 芯片若是\({2^n}\times{x}\) ,则说明需要n根地址线,x根数据线,此外还需要两条读写线和一条片选线
- DRAM芯片的集成度高于SRAM
- sram用两个稳定电路存储,dram用电容暂存,1是有电情况
- 使用地址复用时,地址线减半,增加两条行/列通选线,其中行通选线兼用于片选(仅用于DRAM)
- 随机存取与随机存取存储器(RAM)不同,支持随机存取的存储器不一定是RAM,如u盘基于flash,因此其实是ROM
- DRAM刷新只需要一个存储周期
- 高位交叉存储器在单个存储器中的字是连续存放的,不满足程序的局部性原理(连续读出彼此地址相差一个存储体容量的字);而低位交叉存储器是交叉存放,满足局部性原理
- 双端口存储器具有两套独立读/写口,具有各自的地址寄存器和译码电路,所以可以同时访问同一区间、同一单元
- ROM较慢,不可用作Cache
- 根据历年408真题的描述, 交叉编址方式就是指低位交叉编址,这种情况下最低位\(\log_{2}m\)决定体号
- ROM写速度小于读速度(需要擦除)
- 可能发生访存冲突的情况:给定的访存地址在相邻的m次访问中出现在同一个存储模块内
- 一个存储周期可对所有芯片各读取相同位置的1字节,因此不是从0号芯片存取的\(m*n\)位数据,需要n+1轮周期
主存储器与CPU的连接
- 主存储器通过数据总线、地址总线和控制总线与CPU连接
- 数据总线的位数与工作频率的乘积正比于数据传输率
- 地址总线的位数决定了可寻址的最大内存空间
- 控制总线(读/写)指出总线周期的类型和本次输入/输出操作完成的时刻
主存一般由多个芯片集成而成,通过总线与cpu相连
内存条插槽就是存储器总线,内存条主存中的信息通过内存条的引脚,再通过插槽内的引线连接到主板上,通过主板上的导线连接到CPU芯片
有时需要对芯片字与位进行拓展,满足容量需求
- 位拓展,CPU的数据线数与存储芯片的数据位数不一定相等,此时必须对存储芯片扩位,将多个存储芯片的地址端、片选端和读写控制端相应并联,数据端分别引出,例如八片1位芯片并联,每片作为cpu数据线的一位(需要片选信号CS来进行这种全选)
- 字拓展,将芯片的地址线、数据线、读写控制线相应并联,而由片选信号来区分各芯片的地址范围。每次片选信号只会选中一个芯片
- 字位同时扩展,结合两者,此时各芯片连接地址线的方式相同,但连接数据线的方式不同,而且需要通过片选信号或采用译码器设计连接到相应的芯片
cpu选择存储芯片,称为片选,随后选择存储单元,称为字选
片内的字选通常是由CPU送出的N条低位地址线完成的,地址线直接接到所有存储芯片的地址输入端(N由片内存储容量\(2^N\)决定) 片选信号的产生则分为:
- 线选法:除片内寻址外的高位地址线直接(或经反相器)分别接至各个存储芯片的片选端,,某条地址线为0时表示选中对应芯片,低位线A10~A0用于字选。这样不需要地址译码器,线路简单,地址空间不连续产生浪费。如以下表格所示
- 译码片选法:用除片内寻址外的高位地址线通过地址译码器芯片产生片选信号,例如字选剩下的可用地址线不足时,剩下的若干位用于地址译码,即视作直接的二进制信号
芯片 | A14~A11 |
---|---|
0# | 1110 |
1# | 1101 |
2# | 1011 |
3# | 0111 |
若干注意点:存储芯片,地址,数据,读写命令,片选线:
- 通常选用ROM存放系统程序、标准子程序和各类常数,RAM则是为用户编程而设置的
- CPU的地址线数往往比存储芯片的地址线数要多。通常将CPU地址线的低位与存储芯片的地址线相连,用于字选,译码由存储芯片实现,而CPU地址线的高位则在扩充存储芯片时使用,用于片选,译码由外接译码器实现
- cpu数据线数与存储芯片数据线数也可能不等,需要扩位
- CPU读/写命令线一般可直接与存储芯片的读/写控制端相连,通常高电平为读,低电平为写,有时cpu会分为两条线,\(\overline{RD}\)和\(\overline{WE}\),均为低电平有效,需要分别连接到存储芯片的允许读/写控制端
- 片选有效信号与CPU的访存控制信号\(\overline{MREQ}\)(低电平有效),为高是表示cpu正在访问内存
- 片选信号的译码器的输入地址线是去掉用于产生字数的位的首n根地址线
- MAR的位数必须能访问整个主存地址空间,因此可以大于实际的物理空间
外部存储器
磁盘存储器:
- 容量大,价格低
- 可重复使用
- 可长期保存不易丢失
- 非破坏性读出
- 存取相对较慢,且机械结构对环境有一定要求
组成:
- 磁盘驱动器
- 磁头组件
- 盘片组件
- 磁盘控制器
- 盘片
存储:一块硬盘有若干记录面,记录面有若干磁道,磁盘划分若干扇区,扇区是最小单位
- 磁头数:对应记录面数
- 柱面数:对应磁道数,指不同盘片上垂直分布的各个磁道
- 扇区数
原理:磁头与磁盘相对运动时,电磁转换产生信号
指标:
- 记录密度。记录密度是指盘片单位面积上记录的二进制信息量,通常以道密度、位密度和面密度表示。道密度是沿磁盘半径方向单位长度上的磁道数,位密度是磁道单位长度上能记录的二进制代码位数,面密度是位密度和道密度的乘积
- 磁盘的容量。磁盘容量有非格式化容量和格式化容量之分。非格式化容量是指磁记录表面可利用的磁化单元总数,它由道密度和位密度计算而来;格式化容量是指按照某种特定的记录格式所能存储信息的总量。格式化后的容量比非格式化容量要小
- 平均存取时间。平均存取时间由寻道时间(磁头移动到目的磁道的时间)、旋转延迟时间(磁头定位到要读写扇区的时间)和传输时间(传输数据所花费的时间)三部分构成。
- 数据传输率。磁盘存储器在单位时间内向主机传送数据的字节数,称为数据传输率。假设磁盘转数为r转/秒,每条磁道容量为N字节,则数据传输率为\(D_{r}=r N\)
地址的常见格式(位数取决与需要编址的数量):
驱动器号 | 柱面号 | 盘面号 | 扇区号 |
---|
硬盘的主要操作是寻址、读盘、 写盘。 每个操作都对应一个控制字,硬盘工作时,第一步是取控制字,第二步是执行控制字。
磁盘阵列
将多个独立的物理磁盘组成一个独立的逻辑盘,数据在多个物理盘上分割交叉存储、并行访问,具有更好的存储性能、可靠性和安全性。
- RAID0:无冗余和无校验的磁盘阵列。
- RAID1:镜像磁盘阵列。
- RAID2:采用纠错的海明码的磁盘阵列。
- RAID3:位交叉奇偶校验的磁盘阵列。
- RAID4:块交叉奇偶校验的磁盘阵列。
- RAID5:无独立校验的奇偶校验磁盘阵列。
ssd:基于闪存技术的存储器,与u盘原理相同,由一个或多个闪存芯片和闪存翻译层组成,翻译层翻译cpu请求
一个闪存有B块,每块有P页,数据以页为单位读写,但写任何数量的页需要擦除整个块,因此写相对读更慢,且会消耗固态寿命
- 读一个扇区中数据所用的时间=找磁道的时间+找扇区的时间+磁头扫过一个扇区的时间。找磁道的时间是指磁头从当前所处磁道运动到目标磁道的时间,即寻道时间,可用移动1/2半径的时间估算;找扇区的时间是指磁头从当前所处扇区运动到目标扇区的时间,一般用转半圈的时间估算;磁头扫过一个扇区的时间一般用转一圈的时间除以磁道的扇区数估算
- 磁盘存储器的最小读写单位为一个扇区
高速缓冲存储器
程序访问的局部性原理(略)
高速缓冲技术就是利用局部性原理,把程序中正在使用的部分数据存放在一个高速的、容量较小的Cache中,使CPU的访存操作大多数针对Cache进行,从而提高程序的执行速度。
Cache工作原理
Cache位于存储器层次结构的顶层,通常由SRAM构成
Cache和主存都被划分为相等的块,Cache块又称Cache行,每块由若干字节组成,块的长度称为块长(Cache行长) Cache块数要远少于主存中的块数.其替换过程由硬件实现
CPU与Cache之间的数据交换以字为单位,而Cache与主存之间的数据交换则以Cache块为单位
对Cache的访问可以和主存同步或者异步进行,同步时,命中则主存访问终止,不命中则替换
CPU欲访问的信息已在Cache中的比率称为Cache的命中率。设一个程序执行期间,Cache
的总命中次数为\(N_C\),访问主存的总次数为\(N_m\),则命中率为 \[H=N_{\mathrm{c}}/(N_{\mathrm{c}}+N_{\mathrm{m}})\] \(t_ct_m\)分别是命中与未命中的访问时间,平均访问时间为:
\[T_{\mathrm{a}}=H t_{\mathrm{c}}+(1-H)\,t_{\mathrm{m}}\]
- 数据查找。判断数据是否在Cache
- 地址映射。主存如何存放在Cache,如何进行地址转换
- 替换策略。
- 写入策略。保证数据一致性并提高效率
地址映射
地址映射是指把主存地址空间映射到Cache地址空间,即把存放在主存中的信息按照某种规则装入Cache
Cache中要为每块加一个标记,指明它是主存中哪一块的副本;说明Cache行中的信息是否有效,每个Cache行需要一个有效位。
地址映射方式:
直接映射,主存中的每一块只能装入Cache中的唯一位置,若这个位置已有内容,原来的块将无条件地被替换出去(块冲突概率最高,空间利用率最低), 即:Cache行号=主存块号mod Cache总行数
假设Cache有\(2^c\)行,主存有\(2^m\)块,主存块号的低c位正好是它要装入的Cache行号。给每个Cache行设置一个长为t = m - c
的标记,当主存某块调入Cache后,就将其块号的高t位设置在对应Cache行的标记中
如图,主存地址去除t位的剩下c位,就会对应实际上的Cache地址(如果有效的话)
访存过程:- 根据c位行号找到对应Cache行
- 比较标记与主存高t位标记,若相等且有效位为1,则命中,根据主存的低位地址读取信息
- 不等或有效位0,从主存读出地址的信息,送到对应Cache行,有效位置1,标记设为地址中高t位,数据送到CPU
全相联映射
主存中的每一块可以装入Cache中的任何位置,每行的标记用于指出该行取自主存的哪一块,所以CPU访存时需要与所有Cache行的标记进行比较
优点是比较灵活,Cache块的冲突概率低,空间利用率高,命中率也高;缺点是标记的比较速度较慢,实现成本较高
组相联映射
将Cache分成Q个大小相等的组,每个主存块可以装入固定组中的任意一行,即组间采用直接映射、而组内采用全相联映射的方式
如图,当Q=1时变为全相联映射,当Q=Cache行数时变为直接映射.假设每组有r个Cache行,则称之为r路组相联
Cache组号=主存块号 mod Cache组数(Q) 选定适当的数量,可使组相联映射的成本接近直接映射,而性能上仍接近全相联映射。
地址结构:
标记 | 组号 | 块内地址 |
---|
访存过程:
- 根据组号找到对应的组,将对应Cache组中每个行的标记与主存地址的高位标记进行比较,若相等且有效位1,则命中
- 不命中时,从主存中读出该地址所在的一块信息送到对应Cache组的任意一个空闲行中,将有效位置1并设置标记,同时将该地址中的内容送CPU。
总结
三种映射方式中,直接映射的每个主存块只能映射到Cache中的某一固定行;全相联映射可以映射到所有Cache行;N路组相联映射可以映射到N行。当Cache大小、主存块大小一定时:
- 直接映射的命中率最低,全相联映射的命中率最高
- 直接映射的判断开销最小、所需时间最短,全相联映射的判断开销最大、所需时间最长
- 直接映射标记所占的额外空间开销最少,全相联映射标记所占的额外空间开销最大
主存块的替换算法
直接映射时,主存块对应唯一行,无需考虑替换算法,其他两种情况则需要考虑
- 随机算法:随机地确定替换的Cache块,实现简单,但不符合局部性原理
- 先进先出算法:选择最早调入的行进行替换,优缺点同上
- 近期最少使用算法(LRU):选择近期内长久未访问过的Cache行作为替换的行。对每个Cache行设置一个计数器,用计数值来记录主存块的使用情况,计数值的位数取组大小的对数,规则如下:
- 命中时,所命中的行的计数器清零,比其低的计数器加1,其余不变;
- 未命中且还有空闲行时,新装入的行的计数器置0,其余全加1
- 未命中且无空闲行时,计数值为3的行的信息块被淘汰,新装行的块的计数器置0,其余全加1
- 当集中访问的存储区超过Cache组的大小时,LRU命中率可能变得很低,这种现象称为抖动
- 最不经常使用算法:将一段时间内被访问次数最少的存储行换出,每行设置计数器,每访问一次,被访问的行计数器加1,每次替换选择计数最小的一行,类似LRU
写策略
当对Cache中的内容进行更新时,就需选用写操作策略使Cache内容和主存内容保持一致,分为:
- 全写法(写直通法、write-through):当CPU对Cache写命中时,必须把数据同时写入Cache和主存。当某一块需要替换时,不必把这一块写回主存,用新调入的块直接覆盖即可。实现简单且准确,但效率较低
- 写缓冲:为减少全写法直接写入主存的时间损耗,在Cache和主存之间加一个写缓冲(Write Buffer),CPU同时写数据到Cache和写缓冲中,写缓冲再控制将内容写入主存。写缓冲是一个FIFO队列,频繁写入可能溢出
- 回写法(write-back):当CPU对Cache写命中时,只把数据写入Cache,而不立即写入主存,只有当此块被换出时才写回主存。增加效率,但有可能有不一致问题
- 每个Cache行设置一个修改位(脏位)。1表示修改过,替换时需要写回主存,为0则相反
- 每个Cache行设置一个修改位(脏位)。1表示修改过,替换时需要写回主存,为0则相反
不命中时也有两种情况:
- 写分配法(write-allocate)。加载主存中的块到Cache中,然后更新这个Cache块。更符合局部性原理,但可能开销更大,一般和回写法合用
- 非写分配法(not-write-allocate)只写入主存,不进行调块。一般和全写法合用
现代Cache往往使用指令数据分离的多级Cache
假定设3级Cache,按离CPU的远近可各自命名为L1 Cache> L2 Cache> L3 Cache。 离CPU越远,访问速度越慢,容量越大。
指令Cache与数据Cache分离一般在L1级,此时通常为写分配法与回写法合用。
下图是一个含有两级Cache的系统,L1 Cache对L2 Cache使用全写法,L2 Cache对主存使用回写法,由于L2 Cache的存在,其访问速度大于主存,因此避免了因频繁写时造成的写缓冲饱和溢出。
较大的行可以利用空间局部性增加命中机会,但会放大未命中损失,在项数层面减少命中率
取指令缺失时:
- 程序计数器恢复当前指令的值。
- 对主存进行读的操作。
- 将读入的指令写入Cache中,更改有效位和标记位。
- 重新执行当前指令。
- 标记位地址映射时需要加一个有效位,这个数字乘以Cache行数就是地址映射表大小
- 当CPU访存时,先要到Cache中查看该主存地址是否在Cache中,所以发送的是主存物理地址。只有在虚拟存储器中,CPU发出的才是虚拟地址
- Cache行数 = Cache数据区大小/主存块大小
- Cache位数 = 数据位 + tag位(根据映射方式决定,数值上等于主存地址位数-组号/行号-块内地址位) + 1(脏位,根据写策略决定) +1(有效位,必然存在)
- 对空间局部性良好的连续数据和代码,访问Cache时会把之后会使用的数据调入主存,因此,这次调入的n个数据只有第一个是不命中的
- n路相联映射就会需要n个标记位数的比较器来并行比较
- 有安全性要求时,采用全写法
- 脏位和有效位独立于tag位存在
- 全相联Cache,按先后顺序从0开始分配Cache行
- 一次读突发传送总线事务包括一次地址传送和若干次数据传送,地址传送用一个总线周期,如果是低位交叉读数据,就需要一整个存储周期(第一个存储器读数据)+
存储体数量*总线时间周期
(传输数据) Cache命中时的一条指令执行时间=Cache命中时的CPI * 时钟周期
- 一条指令执行过程中因Cache缺失而导致的平均额外开销=
平均访存次数*Cache缺失率*一次读突发传送总线事务时间
- 物理地址可以同时是页号+偏移量,以及Cache中的块号(标记)+行号+块内地址
虚拟存储器
虚拟存储器将主存或辅存的地址空间统一编址,使用虚拟地址时不用关系具体的地址空间和其实现
用户编程允许涉及的地址称为虚地址或逻辑地址,虚地址对应的存储空间称为虚拟空间或程序空间。实际的主存单元地址称为实地址或物理地址
CPU使用虚地址时,由辅助硬件找出虚地址和实地址之间的对应关系,如果在,则需要进行地址映射,否则需要调入,或者进行置换算法
虚拟存储机制采用全相联映射,每个虚页面可以存放到对应主存区域的任何一个空闲页位置,在处理一致性问题时,采用回写法
虚拟存储器分为页式,段式,和段页式
- 页式虚拟存储器,便于利用空间,实现简单,但最后一页会产生碎片
以页为基本单位。虚拟空间与主存空间都被划分成同样大小的页,主存的页称为实页、页框,虚存的页称为虚页。虚拟地址分为两个字段:虚页号和页内地址。
虚拟地址到物理地址的转换是由页表实现的。页表是一张存放在主存中的虚页号和实页号的对照表,一般驻留内存中
如图,有效位表示是否调入主存中,脏位表示是否修改过,为1时需要把修改写回磁盘;引用位配合置换算法
页表基址寄存器存放进程的页表首地址,然后根据虚拟地址高位部分的虚拟页号找到对应的页表项
- 若装入位为1,则取出物理页号,和虚拟地址低位部分的页内地址拼接,形成实际物理地址;
- 若装入位为0,则说明缺页,需要操作系统进行缺页处理。
快表TLB
由高速缓冲器组成,根据局部性原理缓存一些表项。在地址转换时,首先查找快表,若命中,则无须访问主存中的页表。 快表通常采用全相联或组相联方式。每个TLB项由页表表项内容加上一个TLB标记字段组成,TLB标记用来表示该表项取自页表中哪个虚页号对应的页表项
TLB标记的内容在全相联方式下就是该页表项对应的虚页号;组相联方式下则是对应虚页号的高位部分,而虚页号的低位部分用于选择TLB组的组索引
如图,Cache采用二路组相联方式,TLB采用全相联方式,cpu给出虚拟地址后,比较虚页号和TLB标记字段,命中则通过TLB地址转换,否则查询主存页表,并调入或置换TLB。完成地址转换后,Cache根据上节的步骤,根据物理地址找到对应Cache行,将数据取送cpu
查找时,快表和慢表也可以同步进行
可能的缺失情况:
- TLB缺失,没有对应页表项
- Cache,访问的主存不在Cache
- Page缺失,访问的页面不在主存
第1种组合,此时无须访问主存;第2种和第3种组合都需要访问一次主存;第4种组合需要访问两次主存;第5种组合发生“缺页异常”,需要访问磁盘,并且至少访问两次主存。
Cache缺失处理由硬件完成;缺页处理由软件完成,操作系统通过“缺页异常处理程序”来实现;而TLB缺失既可以用硬件又可以用软件来处理
段式虚拟存储器
段式虚拟存储器中的段是按程序的逻辑结构划分的,各个段的长度因程序而异。把虚拟地址分为两部分:段号和段内地址。虚拟地址到实地址之间的变换是由段表来实现的。段表是程序的逻辑段和在主存中存放位置的对照表。段表的每行记录与某个段对应的段号、装入位、段起点和段长等信息。由于段的长度可变,所以段表中要给出各段的起始地址与段的长度
给出虚拟地址后,根据段号与段表基地址拼接成对应的段表行,然后根据该段表行的装入位判断该段是否已调入主存,调入时将起始地址和段内地址相加就是实际地址
段式存储器具有逻辑独立性,易于编译、管理、修改,保护,多道程序的共享,但容易产生碎片段页式虚拟存储器
把程序按逻辑结构分段,每段再划分为固定大小的页,主存空间也划分为大小相等的页.每个程序对应一个段表,每段对应一个页表,段的长度必须是页长的整数倍,段的起点必须是某一页的起点
虚地址分为段号、段内页号、页内地址三部分。CPU根据虚地址访存时,首先根据段号得到段表地址;然后从段表中取出该段的页表起始地址,与虚地址段内页号合成,得到页表地址;最后从页表中取出实页号,与页内地址拼接形成主存实地址
可以按段实现共享和保护,但两次查表的开销较大
虚拟存储器与Cache
- 相同之处
- 最终目标都是为了提高系统性能,两者都有容量、速度、价格的梯度
- 都把数据划分为小信息块,并作为基本的传递单位,虚存系统的信息块更大
- 都有地址的映射、替换算法、更新策略等问题
- 依据程序的局部性原理应用“快速缓存的思想”,将活跃的数据放在相对高速的部件中
- 不同之处
- Cache主要解决系统速度,而虚拟存储器却是为了解决主存容量
- Cache全由硬件实现,是硬件存储器,对所有程序员透明;而虚拟存储器由OS和硬件共同实现,是逻辑上的存储器,对系统程序员不透明,但对应用程序员透明
- 对于不命中性能影响,因为CPU的速度约为Cache的10倍,主存的速度为硬盘的100倍以上,因此虚拟存储器系统不命中时对系统性能影响更大
- CPU与Cache和主存都建立了直接访问的通路,而辅存与CPU没有直接通路。也就是说在Cache不命中时主存能和CPU直接通信,同时将数据调入Cache;而虚拟存储器系统不命中时,只能先由硬盘调入主存,而不能直接和CPU通信
- 虚存需要通过对操作系统实现地址映射,因此对操作系统的设计者即系统程序员是不透明的,只对应用程序员透明
- Cache和TLB命中必然page命中,其他情况下则没有制约
- 缺页是在地址转换时CPU检测到的一种异常,缺页处理完成后回到发生缺页的指令继续执行
- Cache由SRAM组成;TLB通常由相联存储器组成,也可由SRAM组成
- 主存与Cache之间的信息调度功能全部由硬件自动完成
- 组相联的TLB,需要把虚页号拆分成低位组号与高位标记,分开计算
- 虚拟地址的后若干位是通用的偏移量,可以根据这部分信息算出Cache组号等信息
指令
概念
指令(机器指令)是指示计算机执行某种操作的命令。一台计算机的所有指令的集合构成该机的指令系统,也称指令集。指令系统是指令集体系结构(ISA)中最核心的部分
ISA规定的内容主要包括:指令格式,数据类型及格式,操作数的存放方式,程序可访问的寄存器个数、位数和编号,存储空间的大小和编址方式,寻址方式,指令执行过程的控制方式等。
基本格式
操作码字段 | 地址码字段 |
---|
指令的长度是指一条指令中所包含的二进制代码的位数。指令字长取决于操作码的长度、操作数地址码的长度和操作数地址的个数,与机器字长没有固定的关系,可分为单子长,半字长等
- 零地址指令
- 不需要操作数
- 堆栈计算机中,操作数隐式地从栈顶和次栈顶弹出,结果隐式地压入堆栈
OP |
---|
- 一地址指令,按地址取操作数,运算结束后放回原处;可隐含约定另一个操作数由ACC (累加器)提供,运算结果也将存放在ACC中
OP | \(A_1\) |
---|
- 二地址指令,分别给出目的操作数和源操作数的地址,目的操作数的地址保存本次运算结果
OP | \(A_1\) | \(A_2\) |
---|
- 三地址指令,
OP | \(A_1\) | \(A_2\) | \(A_3(结果)\) |
---|
- 四地址指令,\(A_4\)是下一条将要执行指令的地址
OP | \(A_1\) | \(A_2\) | \(A_3(结果)\) | \(A_4(下址)\) |
---|
- 定长操作码指令,在指令字的最高位部分分配固定的若干位(定长)表示操作码。一般n位操作码字段的指令系统最大能够表示\(2^n\)条指令。
- 扩展操作码指令
变长操作码:指令的操作码字段的位数不固定,且分散地放在指令字的不同位置上
常见的变长操作码方法是扩展操作码:操作码的长度随地址码的减少而增加,不同地址数的指令可具有不同长度的操作码
注意点:
- 短码不能是长码的前缀
- 操作码不能重复 如图,把
1111
作为一种前缀表示操作码拓展到下个非1111的四位
操作类型
- 数据传送
- 算术和逻辑运算
- 移位
- 转移操作,无条件转移(JMP)、条件转移(BRANCH)、调用(CALL)、返回(RET)、陷阱(TRAP)等,转移操作不返回执行,与调用指令根据返回地址返回主程序不同
- I/O操作
- PC存放当前欲执行指令的地址,而指令的地址码字段则保存操作数地址
- 程序控制类指令主要包括无条件转移、有条件转移、子程序调用和返回指令、循环指令等
- 按字节编址时指令长度应该是8的倍数
- 运算器的进位等硬件部分与ISA无关
- 求拓展操作码指令数的最值可以根据地址数由大到小的顺序列方程求解
- 可能的指令格式:操作码-寻址特征-位移量/操作数
- 使用扩展操作码时,设地址位数为n,地址指令操作码每减少一个,就可以多构成\(2^n\)条一地址指令操作码;一地址指令操作码每减少一个,就可以多构成\(2^n\)条零地址指令操作码
指令寻址方式
寻址方式是指寻找指令或操作数有效地址的方式,即确定本条指令的数据地址及下一条待执行指令的地址的方法 指令中的地址码字段称为形式地址(A),结合寻址方式,可以计算出操作数在存储器中的真实地址,这种地址称为有效地址(EA)。 (A)
表示地址为A的数值
寻址方式可分为:
- 指令寻址
- 顺序寻址,程序计数器加一形成下一条指令地址
- 跳跃寻址,下条指令地址由本条指令给出计算方式,修改PC值,根据修改后的PC定位指令
- 数据寻址 ,用操作数地址通过某些方法得出地址
数据寻址的分类
指令格式:
操作码 | 寻址特征 | 形式地址A |
---|
隐含寻址,在指令中隐含操作数的地址,例如使用累加器作为第二操作数地址
有利于缩短指令字长;但需增加存储操作数或隐含地址的硬件。立即数寻址,指令的地址字段指出的不是操作数的地址,而是操作数本身,又称立即数,采用补码表示
指令在执行阶段不访问主存,指令执行时间最短;但A的位数限制了立即数的范围
OP | 立即寻址特征 | 立即数 |
---|
直接寻址,指令字中的形式地址A是操作数的真实地址EA,即EA = A
指令在执行阶段仅访问一次主存,不需要专门计算操作数的地址,但A的位数决定了该指令操作数的寻址范围,操作数的地址不易修改
间接寻址,地址字段给出操作数有效地址所在的存储单元的地址,即EA=(A)
图中,主存字第一位为1时,表示取出的仍不是操作数的地址,即多次间址;主存字第一位为0时,表示取得的是操作数的地址
可扩大寻址范围,便于编制程序(用间接寻址可方便地完成子程序返回);但指令在执行阶段要多次访存,相比寄存器间接寻址不常用寄存器寻址,指令字中直接给出操作数所在的寄存器编号,即EA = Ri
寄存器少所以指令可以较短,执行速度快,支持向量/矩阵运算;但寄存器个数有限寄存器间接寻址,在寄存器Ri中给出的不是一个操作数,而是操作数所在主存单元的地址,即EA=(Ri)
与一般间接寻址相比速度更快,但指令的执行阶段需要访问主存
相对寻址,PC的内容加上指令格式中的形式地址A而形成操作数的有效地址,即EA =(PC)+A,A是相对于当前PC值的位移量,补码表示
操作数的地址随PC值的变化而变化,与指令地址之间总是相差一个固定值,因此便于程序浮动,适用于转移指令
例如,对于转移指令JMP A,当CPU从存储器中取出一字节时,会自动执行(PC)+1->PC。
若转移指令的地址为X,且占2B,在取出该指令后,PC的值会增2,即(PC) = X + 2,这样在执行完该指令后,会自动跳转到X + 2+A的地址继续执行基址寻址,CPU中基址寄存器(BR)的内容加上指令格式中的形式地址A而形成操作数的有效地址,即EA=(BR)+A。其中基址寄存器既可采用专用寄存器,又可采用通用寄存器
基址寄存器内容由操作系统或管理程序确定,主要用于解决程序逻辑空间与存储器物理空间的无关性。在程序执行过程中,基址寄存器的内容不变(作为基地址),形式地址可变(作为偏移量)。
可扩大寻址范围(基址寄存器的位数大于形式地址A的位数);用户不必考虑自己的程序存于主存的哪个空间区域,因此有利于多道程序设计,并可用于编制浮动程序,但偏移量(形式地址A)的位数较短变址寻址,有效地址EA等于指令字中的形式地址A与变址寄存器IX的内容之和,即EA =(IX) + A,其中IX为变址寄存器(专用),也可用通用寄存器作为变址寄存器
在程序执行过程中,变址寄存器的内容可由用户改变(作为偏移量),形式地址A不变(作为基地址)。
可扩大寻址范围(寄存器位数大于A位数,足以表示整个存储空间),适合循环程序
基址寄存器其值不可变,而执行中指令字中的A是可变的;变址寄存器的内容由用户设定,其值在程序执行中可变,而指令字中的A是不可变的
堆栈寻址
堆栈区由特定的寄存器——堆栈指针SP管理
- 寄存器堆栈又称硬堆栈,成本较高
- 主存划出一定区域作为堆栈是软堆栈
使用堆栈的系统,一般指令无操作数,隐含使用堆栈的push,pop作为操作数
- 采用不同寻址方式的目的是为了缩短指令字长,扩大寻址空间
- 以低字节为字地址的存放方式即是小端方式
- 进、出堆栈时对栈顶指针的操作顺序相反,如果进栈是先数据再指针,出栈就是先指针后数据
- 相对寻址中,由于取出本条指令时,PC会自增到下一条指令,因此偏移量加上下一条指令地址才是有效地址
- 跳跃寻址可以实现程序的条件或无条件转移
- 程序计数器(PC)给出下一条指令字的访存地址(指令在内存中的地址),因此取决于存储器的字数;指令寄存器(IR)用于接收取得的指令,因此取决于指令字长
- 无符号减法中出现进位/借位表明被减数更大
- sizeof (数据类型),指的是占用的存储单元,也就是编址的单位
- 内存地址都是无符号数
- 相对寻址转移指令的转移范围取决于PC与偏移量范围的和(主存地址),且必须>=0
- 转移指令计算转移地址,需要对偏移量进行符号拓展,逻辑左移(看指令字长与编址关系),并与自增后的PC相加得到转移地址,与标志位一起送到多路选择器进行转移的判断
- 除了用不同操作码,不同地址数的指令也可以把用不到的操作数地址位全部填0表示操作数个数
汇编
x86处理器中有8个32位的通用寄存器,汇编指令一般有AT&T与intel格式两类
八个32位通用寄存器EAX(4B)等可拆为AX(2B),AX可拆为AH,AL(1B)用:
- EAX(AX) 累加寄存器(Accumulator)
- EBX(BX) 基地址寄存器 (Base Register)
- ECX(CX) 计数寄存器(Count Register)
- EDX(DX) 数据寄存器(Data Register)
- ESI EDI 变址寄存器(Index Register)
- EBP 堆栈基指针(Base Pointer)
- ESP 堆栈顶指针(Stack Pointer)
常见名词:
1
2
3
4
5<reg>表示任意寄存器,形如<reg32>表示32位寄存器
<mem>表示内存地址,包括一些简单表达式
<con>表示常识,如<con8>表示8位常数
[n]表示n对应内存地址的数据,其中n可能是寄存器的值,AT&T使用()表示内存地址数据
R[r]表示寄存器r的内容,M[addr]表示主存单元addr的内容
常见指令
mov:复制数据,但不能用于直接从内存复制到内存 1
2
3
4
5
6
7
8
9mov <reg>, <reg>
mov <reg>, <mem>
mov <mem>, <reg>
mov <mem>, <con>
mov <reg>, <con>
eg.
mov eax, ebx
mov byte ptr [var] , 5
lea:将一个内存地址(而不是其所指的内容)加载到目的寄存器
pop:将push压入的操作数取出,然后(这里与push顺序相反)ESP+4
1
2
3
4
5
6
7push <reg32>
push <mem>
push <con32>
eg.
push [var]
pop [ebx]
add/sub:运算结果均保存到第一个操作数
1
2
3
4
5
6
7
8
9add/sub <reg>, <reg>
add/sub <reg>, <mem>
add/sub <mem>, <reg>
add/sub <reg>, <con>
add/sub <mem>< <con>
eg.
sub eax, 10
add byte ptr [var], 10 //10与var值指示的内存地址的一字节值相加,并将结果保存在var值指示的内存地址的字节中
inc/dec:自增/自减 1
2
3
4
5
6inc/dec <reg>
inc/dec <mem>
eg.
dec eax
inc dword ptr [var] //dword表示四字节的值
imul:带符号整数乘法,第一个操作数必须是寄存器,三操作数版本将后两者的乘积存入第一个操作数,可能溢出,溢出时OF置1
idiv:有符号整数除法指令,唯一的操作数是除数,被除数则为edx:eax中的内容(共64位),操作结果的商送到eax,余数则送到edx
1 | imul <reg32>, <reg32> |
and/or/xor:逻辑与,或,异或,用法一样,结果放到第一个操作数 1
2
3
4
5
6
7
8and <reg>, <reg>
and <reg>, <mem>
and <mem>, <reg>
and <reg>, <con>
and <mem>, <con>
eg.
and eax, 00H
not,对所有位取非;neg对值取负数 1
2
3
4not/neg <reg>/<mem>
eg.
not byte ptr [var]
neg eax
shl/shr:逻辑移位,移动第一个操作数的位数是第二操作数的值 1
2
3
4
5
6
7
8shl <reg>, <con8> / shr <reg>, <con8>
shl <mem>, <con8> / shr <mem>, <con8>
shl <reg>, <cl> / shr <reg>, <cl>
shl <mem>, <cl> / shr <mem>, <cl>
eg.
shl eax, 1
shr ebx, cl
控制指令
jmp:跳转到label指示的地址的指令执行 1
jmp <label>
jcondition:根据cpu状态字条件转移 1
2
3
4
5
6
7
8
9
10
11je <label> (jump when equal)
jne <label> (jump when not equal)
jz <label> (jump when last result was zero)
jg <label> (jump when greater than)
jge <label> (jump when greater than or equal to)
j1 <label> (jump when less than)
jle <label> (jump when less than or equal to)
eg.
cmp eax, ebx
jle done //eax<=ebx时跳转到done
cmp/test:根据运算结果设置cpu状态字,其中cmp相当于不保存结果的sub,test对操作数进行逐位与运算
1
2
3
4
5
6
7
8cmp <reg>, <reg>
cmp <reg>, <mem>
cmp <mem>, <reg>
cmp <reg>, <con>
eg.
jz eax, eax #测试eax是否是0
jz xxxx #为零则置标志ZF为1,转跳到xxxx处执行
过程调用
call/ret:call将当前指令地址入栈,随后无条件转移到label(保存调用之前的地址),ret用于返回到之前保存的指令地址(通过出栈原先指令的地址并无条件转移并执行) 1
2call <label>
ret
过程P调用过程Q的执行步骤:
- P将入口参数(实参)放到Q能访问到的地方。
- P将返回地址存到特定的地方,然后将控制转移到Q。(
call
指令) - Q保存P的现场(通用寄存器的内容),并为自己的非静态局部变量分配空间。
- 执行过程Q。
- Q恢复P的现场,将返回结果放到P能访问到的地方,并释放局部变量所占空间。
- Q取出返回地址,将控制转移到P。(
ret
)
调用者和被调用者需共享(用户可见的)寄存器,规定:
- 寄存器EAX、ECX和EDX是调用者保存寄存器,当P调用Q时,若Q需用到这些寄存器,则由P将这些寄存席的内容保存到栈中,并在返回后由P恢复它们的值
- 寄存器EBX、ESI和EDI是被调用者保存寄存器,当P调用Q时,Q必须先将这些寄存器的内容保存在栈中才能使用它们,并在返回P之前先恢复它们的值
每个过程都有自己的栈区,称为栈帧,一个栈由若干栈帧组成,寄存器EBP指示栈帧的起始位置,寄存器ESP指示栈顶,栈从高地址向低地址增长,出入栈只更改ESP
1 | leave指令功能相当于以下两条指令的功能: |
选择指令
if-else: 1
2
3
4
5
6
7
8
9
10
11
12
13
14if(test expr) # test_expr是一个整数表达式,它的取值为0 (假),或为非0 (真)
then_statement
else
else_statement
即过程:
t=test expr;
if (!t)
goto false;
then_statement
goto done;
false:
else_statement
done:
循环指令
do-while和while: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26do
body_statement
while(test_expr);
while (test_expr)
body_statement
#while与do-while的不同:第一次执行body_statement之前,就会测test_expr的值,循环有可能中止
即:
do-while的过程:
loop:
body_statement
t=test_expr;
if (t)
goto loop;
while的过程:
t=test_expr;
if (!t)
goto done;
loop:
body_statement
t=test_expr;
if(t)
goto loop;
done:
for: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15for(init expr; test expr; update expr)
body statement
过程:
init expr;
t=test_expr;
if(!t)
goto done;
loop:
body_s tatement
update expr;
t=test_expr;
if(t)
goto loop;
done:
指令系统
- 复杂指令系统计算机(CISC),典型如x86架构
- 数量一般200以上
- 长度不定,格式,寻址方式较多
- 访存的指令不受限制
- 指令使用频度差别大,执行时间差别大,显示出二八定律,但也可以实现指令流水线
- 控制器大多用微程序控制
- 难以优化编译
- 精简指令系统计机(RISC),典型的有ARM、MIPS架构的计算机
- 指令较简单,复杂功能需要组合,一般少于100
- 长度固定,格式更少
- 只有Load/Store指令可以访存,其他指令用寄存器进行
- cpu的通用寄存器更多
- 必须实现指令流水线,指令时间较短
- 硬布线控制为主,少见微程序
- 重视编译优化
RISC的优点:
- 更能充分利用VLSI芯片的面积,硬布线逻辑比微程序控制器占地更小
- 提高运算速度,(指令长度一致、按边界对齐存放、仅Load/Store指令访存便于形成流水线)
- 便于设计,成本低且可靠
- 利于编译程序代码优化
cpu
基本功能结构
中央处理器(CPU)由运算器和控制器组成。其中,控制器的功能是负责协调并控制计算机各部件执行程序的指令序列,包括取指令、分析指令和执行指令;运算器的功能是对数据进行加工。基本功能有:
- 指令控制,即程序的顺序控制
- 操作控制,控制各个部件按指令的要求动作
- 时间控制(提供按时间顺序的控制信号)
- 数据加工,算术与逻辑运算
- 中断处理
运算器
- 算术逻辑单元
- 暂存寄存器,寄存主存读来的数据(对应用程序员透明)
- 累加寄存器ACC,通用寄存器,可作为加法的输入,可暂存ALU运算信息
- 通用寄存器组,AX,BX,CX,DX,SP等,存放数据,其中SP是堆栈指针,指示栈顶地址
- 程序状态字寄存器PSW,存放溢出标志OF,符号SF,零ZF,进位CF
- 移位器,进行移位运算
- 计数器CT,控制乘除的操作步数
控制器
指挥全机协调工作,基本功能是执行指令,指令的执行是由控制器发出的一组微操作实现的,分为硬布线与微程序控制器
- 程序计数器PC,指出欲执行指令在主存的存放地址,可以自增
- 指令寄存器IR,保存当前正在执行的指令
- 指令译码器,对操作码字段译码
- 存储器地址寄存器MAR
- 存储器数据寄存器MDR
- 时序系统,产生时序信号,用统一时钟分频得到
- 微操作信号发生器,根据IR内容,PSW内容与时序信号,产生各种控制信号
通用寄存器组、程序状态字寄存器,程序计数器对用户可见,且可编程
存储器地址寄存器、存储器数据寄存器、指令寄存器对用户透明,不可对其编程
- CPU的位数n与数据总线线数相等
- PC的值可以在cpu执行指令过程的取指周期修改
- 转移指令需要判断转移是否成功,不成功的话下一条指令依旧是自增地址
- 程序计数器存放指令地址,需要和存储器地址位数一致
- 指令寄存器可以被用户编程,不能由通用寄存器代替
- 间址周期结束时,CPU内寄存器MDR中的内容为操作数地址
指令执行过程
CPU从主存中取出并执行一条指令的时间称为指令周期,常用若干机器周期(cpu周期)来表示,一个机器周期又包含若干时钟周期
每个指令周期内的机器周期数可以不等,每个机器周期内的节拍数也可以不等
如果使用中断机制,CPU在每条指令执行结束前,都要发中断查询信号,若有中断请求,则CPU进入中断响应阶段,又称中断周期
带有间址周期、中断周期的指令周期:
取指周期 | 间址周期 | 执行周期 | 中断周期 |
---|
其中,取指周期访存取指令,间址周期取有效地址,执行周期取操作数,中断周期保存程序断点
为了区别不同的工作周期,在CPU内设置4个标志触发器FE、IND、EX和INT,它们分别对应取指、间址、执行和中断周期,并以“1”状态表示有效
中断周期中的进栈操作是将SP减1(堆栈都是向低地址增加)
数据流
数据流是根据指令要求依次访问的数据序列。
取指周期
间址周期 例如一次间址中,将指令中的地址码送到MAR并送至地址总线,此后CU向存储器发读命令,以获取有效地址并存至MDR。
间址周期的数据流向如下:- Ad(IR)(或MDR)①MAR②地址总线③主存。
- CU发出读命令④控制总线⑤主存。
- 主存⑥数据总线⑦MDR (存放有效地址)。
其中 ,Ad(IR)表示取出IR中存放的指令字的地址字段。
执行周期 取操作数,并根据IR中的指令字的操作码通过ALU操作产生执行结果
中断周期
处理中断请求。假设程序断点存入堆栈中,并用SP指示栈顶地址,而且进栈操作是先修改栈顶指针,后存入数据
断点
指令执行方案:
- 单指令周期。所有指令都选用相同的执行时间来完成,串行完成,每条花费一个时钟周期,因此时钟周期取决于时间最长的指令
- 多指令周期。不同类型的指令选用不同的执行步骤,称为多指令周期方案,串行执行,但可以用不同时钟周期来完成不同指令
- 流水线方案。指令可以并行执行,尽可能让每个时钟脉冲周期内完成一条指令的执行过程,让多条指令同时运行,但各自处在不同的执行步骤中
- 转移指令的原理是更改PC,因此指令地址总是PC的值
- 机器周期通常由存取周期(相对最长)确定
- 取指周期和操作只和指令字长(与存储字长的大小关系)有关
- 冯•诺依曼计算机根据指令周期的不同阶段来区分从存储器取出的是指令还是数据
数据通路
数据在功能部件之间传送的路径称为数据通路,包括数据通路上流经的部件
基本结构:
- CPU内部单总线方式。将所有寄存器的输入端和输出端都连接到一条公共通路上,存在冲突问题,性能差
- CPU内部多总线方式。将所有寄存器的输入端和输出端都连接到多条公共通路上
- 专用数据通路方式。根据指令执行过程中的数据和地址的流动方向安排连接线路,硬件多但效率高
图中,字母加“in”表示该部件的允许输入控制信号;字母加“out”表示该部件的允许输出控制信号。
内部总线是指同一部件,如CPU内部连接各寄存器及运算部件之间的总线;系统总线是指同一台计算机系统的各部件,如CPU、内存和各类I/O接口间互相连接的总线。
组成:
- 组合逻辑元件(操作元件),任何时刻产生的输出仅取决于当前的输入。组合电路不含存储信号的记忆单元,也不受时钟信号的控制,输出与输入之间无反馈通路,信号是单向传输的,包括:
- 加法器
- ALU
- 译码器(操作码或地址码译码,n位输入转化成 \(2^n\) 个输出)
- 多路选择器(控制信号
Select
来确定选择哪个输入被输出) - 三态门(控制信号
EN
决定信号线的通断)
- 时序逻辑元件(状态元件):任何时刻的输出不仅与该时刻的输入有关,还与该时刻以前的输入有关,包含存储信号的记忆单元,在时钟节拍下工作。包括:
- 通用寄存器组
- PC
- 状态/移位/暂存/锁存寄存器
过程:
寄存器之间的数据传送(在寄存器和总线之间有两个控制信号:Rin和Rout,in信号使总线向寄存器R输入数据,out信号让寄存器输出数据给总线)
1
(PC) -> MAR //PCout 和 MARin 有效,PC内容->MAR
主存与cpu的数据传送
1
2
3
4
5
6
7
8
9
10取指阶段:
(PC) -> MAR //PCout 和 MARin 有效,PC 内容->MAR
1 -> R //CU发读命令
MEM(MAR) -> MDR (PC)+1->PC //MDRin有效
(MDR) -> IR //MDRout和IRin有效,现行指令->IR
将数据写入主存:
(R1) -> MDR //R1out 和 MDRin 有效
(R2) -> MAR //R2out 和 MARin 有效
MDR -> MEM(MAR) //MDRout有效,CU发出写命令算术或逻辑运算,alu没有存储功能,相加的两个数必须在ALU的两个输入端同时有效,所以需要暂存区Y
1
2
3
4
5
6(MDR) -> MAR //MDRout和MARin有效,操作数有效地址→MAR
1 -> R //CU发读命令
MEM(MAR) -> MDR //操作数从存储器→MDR
(MDR) -> Y //MDRout和Yin有效,操作数→Y
(ACC) + (Y) -> Z //ACCout和ALUin有效,CU向ALU发加命令,结果->Z
(Z) -> ACC //Zout和ACCin有效,结果→ACC
- 单总线数据通路将所有寄存器的输入输出端都连接在一条公共通路上,一个时钟内只允许一次操作,无法用于单周期处理器
- 内部总线是指同一部件,如CPU内部连接各寄存器及运算部件之间的总线;系统总线是指同一台计算机系统的各部件,如CPU、内存和各类I/O接口间互相连接的总线
- 一个时钟周期内控制信号并不会变化
- 数据通路包括ALU、通用寄存器、状态寄存器、Cache、MMU、浮点运算逻辑、异常和中断处理逻辑
- ALU内部没有寄存器,需要计算时一般一个暂存器输入加上总线直接输入,并用一个控制信号来表示运算类型(Add,Sub等)
- 信号SRout所控制的部件是一个三态门,用于控制移位器与总线之间数据通路的连接与断开
- 总线可以通过一个二路选择器连接ALU的输入端,一个用来PC自增,一个用来输入ALU
控制器
主要连接关系:
- 运算器部件通过数据总线与内存储器,IO设备传送数据
- IO设备通过接口电路与总线相连
- 存储器,IO设备与地址,控制,数据总线连接
- 控制器从数据线接受指令,从运算器接受指令转移地址,送地址到地址总线,并产生控制信号
控制器的主要功能:
- 从主存取指令,并指出下一个指令的地址
- 对指令译码,产生控制信号
- 指挥主存,CPU,IO设备的数据流动方向
根据控制器产生微操作控制信号的方式的不同,控制器可分为硬布线控制器和微程序控制器,两者的PC和IR相同
硬布线控制器
CU的输入信号来源:
- 指令译码器译码产生的指令信息
- 时序系统产生的机器周期信号和节拍信号
- 来自执行单元的反馈信息,即标志。
- 系统总线(控制总线)的控制信号
CU的输入来自操作码译码电路ID、节拍发生器及状态标志,其输出到CPU内部或外部控制总线上
时序系统:
- 时钟周期,时钟信号控制节拍发生器,可以产生节拍,每个节拍的宽度正好对应一个时钟周期。
- 机器周期。机器周期可视为所有指令执行过程中的一个基准时间。通常以存取周期作为基准时间(从存储器读一个指令字)在一个机器周期里可完成若干微操作
- 指令周期
- 微操作命令分析,需要发出各种操作命令(控制信号)序列
1 | 取指周期: |
控制方式:
- 同步控制,系统有一个统一的时钟,所有的控制信号均来自这个统一的时钟信号,一般最长的操作序列为标准,使用相同的节拍为机器周期,电路简单但低效
- 异步控制,不存在基准时标信号,部件间用应答方式联络,速度快但电路复杂
- 联合控制,不同的指令大部分同步控制,少部分异步控制
设计步骤:
- 列出操作时间表,包括各个机器周期、节拍下的每条指令完成的微操作控制信号
- 微操作信号综合,根据时间表写出各个操作控制信号的逻辑表达式,如
微操作控制信号=机器周期^节拍^脉冲^操作码人机器状态条件
- 画出微操作命令的逻辑图,并用逻辑门电路实现。
表中FE、IND和EX为CPU工作周期标志,T0〜T2为节拍,I为间址标志,指令若有表中所列出的微操作命令,其对应的单元格内为1
取指周期的T2时刻,若测得I=1,则IND触发器置“1”,标志进入间址周期;若I= 0,则EX触发器置“1”,标志进入执行周期。同理,在间址周期的T2时刻,若测得IND = 0(表示一次间接寻址),则EX触发器置“1”,进入执行周期;若测得IND=1 (表示多次间接寻址),则继续间接寻址。在执行周期的T2时刻,CPU要向所有中断源发中断查询信号,若检测到有中断请求并满足响应条件,则INT触发器置“1”,标志进入中断周期。
微程序控制器
微程序控制器采用存储逻辑实现,也就是把微操作信号代码化,每条机器指令转化成为一段微程序并存入一个专门的存储器(控制存储器)中,微操作控制信号由微指令产生。
一些名词
一条机器指令可以分解成一个微操作序列,微操作是原子化不可分的操作,微程序控制的计算机中,将控制部件向执行部件发出的各种控制命令称为微命令,是构成控制序列的最小单位
微命令和微操作是一一对应的。微命令是微操作的控制信号,微操作是微命令的执行过程。
可以同时产生的微命令是相容的,否则是互斥的,这是相互之间的关系,一个微命令可以和一些相容,一些互斥
微指令是若干微命令的集合。存放微指令的控制存储器的单元地址称为微地址。执行一条微指令的时间称为微周期,一般是一个时钟周期
微指令的构成:
- 操作控制字段,又称微操作码字段,用于产生某一步操作所需的各种操作控制信号。
- 顺序控制字段,又称微地址码字段,用于控制产生下一条要执行的微指令地址。
主存储器用于存放程序和数据,在CPU外部,用RAM实现;控制存储器(CM)用于存放微程序,在CPU内部,用ROM实现。
程序是指令的有序集合,用于完成特定的功能;微程序是微指令的有序集合,一条指令的功能由一段微程序来实现。
微程序由微指令组成,用于描述机器指令,实际上是机器指令的实时解释器,是由计算机设计者事先编制好并存放在控制存储器中的,对程序员透明。程序最终由机器指令组成
与MAR和IR对标的是微地址寄存器CMAR(存放控制存储器的读/写微指令的地址)与微指令寄存器CMDR/μIR(存放控制存储器读出的微指令)
基本组成
- 控制存储器CM,存放微程序,用ROM构成
- 微指令寄存器,存放CM取出的微指令,位数等于微指令字长
- 微地址形成部件,形成微地址,保证其连续进行
- 微地址寄存器,接受地址形成部件送来的微地址
工作过程
- 执行取微指令操作,将机器启动时,取指微程序入口地址(一般是CM的0号单元)送入CMAR,从CM读出微指令送入CMDR,取指微程序执行过程中,主存取出的机器指令会被存入IR
- 机器指令操作码通过微地址形成部件产生该指令对应的微程序入口地址,送入CMAR
- CM逐条取出微指令执行
- 执行完一个微程序后,回到1.继续循环
通常,一条机器指令对应一个微程序,取指令的微命令会被统一编成微程序,用于从主存取出指令送入IR,间址和中断周期也可以编成公共微程序,这三者和机器指令数的和就是总微程序数
微指令的编码(控制)方式
指如何对微指令的控制字段进行编码,以形成控制信号
直接编码(控制),微指令的微命令字段中每位都代表一个微命令,约定某位置0表示哪个微命令
字段直接编码,将微指令的微命令字段分成若干小字段,每个字段独立编码,每种编码代表一个微命令,且各字段编码含义单独定义,与其他字段无关
- 互斥性微命令分在同一段内,相容性微命令分在不同段内。
- 每段信息位较少
- 每段留出一个状态,表示字段是否不操作
字段间接编码(隐式编码),一个字段的某些微命令需由另一个字段中的某些微命令来解释,缩短微指令字长,但削弱了微指令的并行控制能力,一般用于辅助
微指令的地址形成方式
通电时第一条微指令的地址可由专门的硬件电路产生,也可由外部直接向CMAR输入微指令的地址,这个地址即为取指周期微程序的入口地址。
- 基本类型
- 断定方式,直接由微指令的下地址字段指出,微指令格式中设置一个下地址字段,由微指令的下地址字段直接指出后继微指令的地址
- 根据机器指令的操作码形成。机器指令取至指令寄存器后,微指令的地址由操作码经微地址形成部件形成
- 其他方式
- 增量计数器法,类似PC的自增1,适用于指令地址连续情况
- 根据各种标志决定
- 测试网络形成
- 硬件直接产生
微指令格式
- 水平型,指令字中的一位对应一个控制信号,有输出为1,否则为0。微程序短,指令执行时间短,可以并行操作;但指令长,编写困难
- 垂直型,设置操作码字段,由其规定指令功能,每个指令定义一种操作。指令较短,编写简单;但效率低,执行时间长,微程序长
- 在垂直型的基础上增加一些不太复杂的并行操作
控制单元的设计步骤
- 写出对应机器指令的微操作命令及节拍安排,例如取指时和硬布线不同的是T2节拍将IR的OP送往微地址形成部件,硬布线则送往指令译码器;且多一条将下一条微指令地址送到CMAR的操作
1
2
3
4
5
6
7取指操作
(PC)->MAR, 1-*R
Ad (CMDR) ->CMAR //将微指令下地址字段送至CMAR
M(MAR)->MDR, (PC) + 1->PC
Ad (CMDR)-*>CMAR
(MDR)->IR
OP (IR)->微地址形成部件->CMAR - 确定微指令格式
- 编写微指令码点
在一台微程序控制的计算机中,假如能根据用户的要求改变微程序,则这台机器就具有动态微程序设计功能,需要可写控制寄存器的支持例如EPROM
在普通的微程序计算机中,从主存取出的每条指令是由放在控制存储器中的微程序来解释执行的,通过控制线对硬件进行直接控制
若硬件不由微程序直接控制,而是通过存放在第二级控制存储器中的毫微程序来解释的,这个第二级控制存储器就称为毫微存储器,直接控制硬件的是毫微微指令
总结
- 硬布线控制器的优点是由于控制器的速度取决于电路延迟,所以速度快;缺点是由于控制逻辑用电路实现,难以额外修改
- 微程序控制器的优点是更规整灵活;缺点是采用存储程序,取指访存较为影响速度
- 控制存储器中存放微指令
- 通常控制存储器采用ROM组成
- 指令周期是从一条指令启动到下一条指令启动的间隔时间,而CPU周期是机器周期,是指令执行中每步操作所需的时间
- 状态条件寄存器属于运算器
- 主存可以用RAM和ROM实现
- 微指令寄存器对汇编程序员是透明的
- pc自增和取指,存IR和取IR操作码给Id可以放在同一个节拍(硬布线中)
异常和中断机制
CPU内部产生的意外事件被称为异常,也称内中断,CPU外部的设备向CPU发出的中断请求被称为中断或者外中断
- 异常是CPU执行一条指令时,由CPU在其内部检测到的、与正在执行的指令相关的同步事件;
- 中断是由外部设备触发的、与当前正在执行的指令无关的异步事件。
一般来说,cpu检测到异常和中断时,打断当前程序,保护现场,然后处理异常,如果能处理完成,则回到程序的当前指令或下一条指令(可能刚执行完一个指令就触发异常),否则终止程序
异常与中断的分类:
- 异常(按软硬件)
- 硬故障中断,硬连线异常引起
- 程序性异常(软件中断),cpu内部执行指令引起的错误,如除0,溢出等
- 异常(按产生原因)
- 故障,引起故障的指令启动后、执行结束前被检测到的异常事件,如缺页,除0等,前者可以回到断点继续执行,后者必须终止程序。软件中断
- 自陷Trap,执行这种指令后,自动根据不同“陷阱”类型进行相应的处理,然后返回到自陷指令的下一条指令(如果是转移自陷指令则返回转移地址)执行。软件中断
- 终止,执行指令时出现无法继续执行的硬件问题,只能中断来重启系统。硬件中断
- 中断,外部I/O设备通过特定的中断请求信号线向CPU提出中断请求,CPU每执行完一条指令就检查中断请求信号线,如果检测到中断请求,则进入中断响应周期
- 可屏蔽中断,通过可屏蔽中断请求线INTR向CPU发出的中断请求,可以选择屏蔽
- 不可屏蔽中断,通过专门的不可屏蔽中断请求线NMI向CPU发出的中断请求,需要cpu立即处理
中断响应:
- 关中断,通常通过设置"中断允许"(IF)触发器来实现,置0不响应中断
- 保存断点,将程序断点(返回地址)与状态字寄存器送入栈或寄存器中,一般是栈,便于嵌套处理
- 识别中断,转到相应处理程序
- 软件识别,CPU设置一个异常状态寄存器,用于记录异常原因,操作系统按优先级顺序查询该寄存器,检测类型,先查到的先处理,转到内核对应处理程序,多用于异常
- 硬件识别(向量中断),异常或中断处理程序的首地址称为中断向量,所有中断向量都存放在中断向量表中。在中断向量表中,中断类型号和中断向量一一对应,因而可以根据类型号快速找到对应的处理程序
中断响应过程是原子化的,响应过程结束后,CPU就从PC中取出中断服务程序的第一条指令开始执行,直至中断返回,处理过程由软硬件协同实现
- CPU所执行指令的地址序列称为CPU的控制流。在程序正常执行时,通过顺序执行指令或转移指令得到的控制流称为正常控制流。在正常执行过程中,因遇到异常或中断事件而引起用户程序的正常执行被打断所形成的意外控制流,称为异常控制流
- 部分异常/中断的处理是硬件进行
- 外部中断请求信号的检测总是在一条指令执行完之后,取下一条指令之前,内部中断则在指令执行过程中出现
- 典型的外中断(外是相当于cpu和内存):定时器到达,网络数据包到达,IO相关,用户输入信号(如ctrl-c),硬件相关
- 典型的内中断/异常:地址非法/越界,浮点数上溢(下溢就是0),缺页,计算溢出,除0,用户程序执行特权指令,存取访问错误,切换到内核态,时间片到期
指令流水线
指令流水线技术用于提高处理机并行性:
- 时间上并行,将任务分解为不同子阶段,每个阶段在不同功能部件上并行执行,称为流水线技术
- 空间上并行,一个处理机内设置多个执行相同功能的部件,并行工作,称为超标量处理机
对应指令执行过程的分解:
- 取指,从指令寄存器或者Cache取指令
- 译码/读寄存器:控制器对指令译码,从寄存器取操作数
- 执行/计算地址:执行运算操作或计算地址
- 访存:读写主存
- 写回:指令执行结果写回寄存器堆
如图,第k+1条指令的取指提前到k条指令的译码,从而前者的译码与后者的执行阶段可以并行
理想情况下每个指令用一个时钟周期完成,实际的流水线设计中,以最复杂操作的阶段数量与时间为准,也就是最长阶段的用时*
阶段数量,这样流水线执行单条指令的耗时大于等于单周期处理机,但总时间大大减少
对指令集的要求:
- 指令长度一致或近似,简化取指和译码的时间差别与译码难度
- 指令格式一致或近似,尽量使源寄存器位置相同,可以直接取寄存器减少用时
- 采用Load/Store统一访存,便于通过简化LS指令来减少周期数量
- 数据与指令对齐存放,减少访存次数
基本实现
- IF段包括程序计数器(PC)、指令存储器、下条指令地址的计算逻辑;
- ID段包括操作控制器、取操作数逻辑、立即数符号扩展模块;
- EX段主要包括算术逻辑单元(ALU)、分支地址计算模块;
- MEM段主要包括数据存储器读写模块;
- WB段主要包括寄存器写入控制模块。
每个流水段后面都需要增加一个流水段寄存器,锁存处理完成的数据和控制信号
各种寄存器和数据存储器均采用统一时钟CLK进行同步,每来一个时钟,就会有一条新的指令进入流水线IF段;同时流水段寄存器会锁存前段加工处理完成的数据和控制信号,为下一段的功能部件提供数据输入。
即每两个相邻的流水段之间设置一个流水段寄存器,存放前一个流水段中产生的并需要传输到其后所有流水段的信息,包括各种数据(PC、指令、立即数、运算结果、寄存器号等)和控制信号两大类信息。每个流水段的功能不一样,所需传递的信息也不同,因此各流水段寄存器的长度也不同
流水线执行过程:
- 取指,取出PC值,计算PC+4送入PC输入端,通过PC值取指令字,PC+4与指令字(通过RD输出端)送入IF/ID流水寄存器,以备后续使用,时钟到来时将更新后的PC值和指令字锁存到IF/ID流水寄存器中;本条指令\(I_1\)进入ID段,IF段取出下条指令\(I_2\)
- 译码/读寄存器ID,控制器通过流水寄存器生产后续需要的控制信号,例如读写寄存器,符号拓展指令字,多路选择器生成寄存器编号,这些数据与信号连同PC+4锁入流水寄存器。指令\(I_1\)进入EX段,下条指令\(I_2\)进入ID段,下下条指令\(I_3\)进入IF段
- 执行/计算地址EX,功能由具体指令确定,不同指令经ID段译码后得到不同的控制信号,可用于生成访存,分支地址等。时钟到来后,数据和后段需要的控制信号都会锁存到EX/MEM流水寄存器中;指令\(I_1\)进入MEM段,后续指令\(I_2I_3I_4\)分别进入EX、ID、IF段
- 访存MEM,由具体指令确定功能,例如根据EX/MEM流水寄存器的访存地址进行读写。时钟到来后,这些数据和后段需要的控制信号都会锁存到MEM/WB流水寄存器中,EX/MEM的信号与数据也会一起送入;指令\(I_1\)进入WB段,后续指令\(I_2I_3I_4I_5\)分别进入MEM、EX、ID、IF段
- 写回WB,由具体指令确定功能,将MEM/WB流水寄存器中数据存储器读出的数据写回指定寄存器;时钟到来时会完成数据写入寄存器,指令\(I_1\)离开流水线。此时,指令\(I_2\)进入最后的WB段,指令\(I_3I_4I_5\)分别进入MEM、EX、ID段,指令\(I_6\)进入IF段
分类
- 根据流水线使用的级别的不同,流水线可分为部件功能级流水线、处理机级流水线和处理机间流水线。
- 部件功能级流水就是将复杂的算术逻辑运算组成流水线工作方式。例如,可将浮点加法操作分成求阶差、对阶、尾数相加以及结果规格化等4个子过程。
- 处理机级流水是把一条指令解释过程分成多个子过程,如取指、译码、执行、访存及写回5个子过程。
- 处理机间流水是一种宏流水,其中每一个处理机完成某一专门任务,各个处理机所得到的结果需存放在与下一个处理机所共享的存储器中。
- 部件功能级流水就是将复杂的算术逻辑运算组成流水线工作方式。例如,可将浮点加法操作分成求阶差、对阶、尾数相加以及结果规格化等4个子过程。
- 按流水线可以完成的功能,分为单功能多功能
- 单功能流水线指只能实现一种固定的专门功能的流水线;
- 多功能流水线指通过各段间的不同连接方式可以同时或不同时地实现多种功能的流水线
- 按同一时间内各段之间的连接方式,流水线可分为静态流水线和动态流水线。
- 静态流水线指在同一时间内,流水线的各段只能按同一种功能的连接方式工作。
- 动态流水线指在同一时间内,不同的段可以进行不同运算,效率更高,控制更复杂
- 按流水线的各个功能段之间是否有反馈信号,流水线可分为线性流水线与非线性流水线。
- 线性流水线中,从输入到输出,每个功能段只允许经过一次,不存在反馈回路。
- 非线性流水线存在反馈回路,从输入到输出过程中,某些功能段将数次通过流水线,适合进行线性递归
冒险
可能遇到一些情况使得流水线无法正确执行后续指令而引起流水线阻塞或停顿,这种现象称为流水线冒险
- 结构冒险,多条指令在同一时刻争用同一资源而形成的冲突,也称为资源冲突,解决方法:
- 前一指令访存时,使后一条相关指令(以及其后续指令)暂停一个时钟周期
- 一个部件每条指令只能使用一次,且只能在特定阶段使用
- 单独设置数据存储器和指令存储器,使取数和取指令操作各自在不同的存储器中进行,如L1Cache将指令数据分离,避免这种问题
- 数据冒险,下一条指令会用到当前指令计算出的结果,此时这两条指令发生数据冲突,分为:
- 写后读RAW,当前指令将数据写入寄存器后,下一条指令才能从该寄存器读取数据,否则读到的就是旧数据
- 读后写WAR,表示当前指令读出数据后,下一条指令才能写该寄存器,否则读到的就是新数据
- 写后写WAW,当前指令写入寄存器后,下一条指令才能写,否则寄存器的值就不是最新值
- load-use问题,数据在mem阶段存入主存前就要被读出(涉及到主存无法用旁路解决,只能阻塞或者编译优化)
- 解决方案:
- 把遇到数据相关的指令及其后续指令都暂停一至几个时钟周期,直到数据相关问题消失后再继续执行,可分为硬件阻塞(stall,根据指令流程分析耗时)和软件插入“NOP”(空)指令两种方法
- 设置相关专用通路,不经过寄存器,直接把前一条指令的ALU的计算结果作为下一条的输入数据开始计算过程,称为数据旁路技术
- 编译器对数据相关指令编译优化,调整到合理顺序
- 控制冒险,执行转移、调用或返回等改变原有顺序的指令时,会改变PC值,会造成断流,从而引起控制冒险。解决方法:
- 延迟后续指令
- 对转移指令进行分支预测,尽早生成转移目标地址,分为简单(静态)预测(每次的预测结果一样,若总是预测条件不满足,跳过分支指令,直接执行后续指令)和动态预测(根据历史进行预测,准确率更高)
- 预取转移成功和不成功两个控制流方向上的目标指令。
- 加快和提前形成条件码
- 提高转移方向的猜准率
性能指标
吞吐率,单位时间内流水线所完成的任务数量,或输出结果的数量。 \[\mathrm{TP}={\frac{n}{T_{k}}}\] n 是任务数,\(T_k\)是处理完n个任务所用的总时间。设k为流水段的段数,Δt为时钟周期。
在输入流水线中的任务连续的理想情况下,一条k段流水线能在上k+n-1
个时钟周期内完成n个任务。
\[\mathbf{TP}={\frac{n}{(k+n-1)\Delta t}}\]加速比,同样任务不使用流水线与使用流水线所用的时间之比
\[s={\frac{T_{\mathrm{0}}}{T_{\mathrm{K}}}}\]
\(T_0\)是不用流水线的总时间,\(T_k\)流水线所用的总时间
\[S={\frac{k n\Delta t}{(k+n-1)\Delta t}}={\frac{k n}{k+n-1}}\]
高级流水线技术
超标量流水线技术也称动态多发射技术,每个时钟周期内可发多条独立指令,以并行操作方式将两条或多条指令编译并执行,为此需配置多个功能部件,
CPI<1
,不能调整指令的执行顺序,配置多个功能部件通过编译优化技术,把可并行执行的指令搭配起来
多数超标量CPU都结合动态流水线调度技术,通过动态分支预测等手段,指令不按顺序执行,这种执行方式称为乱序执行超长指令字技术也称静态多发射技术,编译程序将多条能并行操作的指令组合成一条具有多个操作码字段的超长指令字(可达几百位),需要多个处理部件
超流水线技术,划分更短的功能段与时钟周期,提高流水线主频,也就是级数来提升流水线性能,会增加寄存器开销,CPI依旧=1
- 按序流动的流水线只可能出现RAW相关(某条指令要读取上一条指令所写入的寄存器)
- 非按序流动的流水线中,RAW,WAR,WRW都可能发生
- 吞吐能力是指单位时间内完成的指令数,稳定后的m段流水线和m个处理器cpu吞吐能力相同
- 译码和读寄存器通常在一个周期
- 数据通路不包括控制部件!!!
- 每访问一次内存数据就会查一次TLB,缺页后需要等调页后再重新访问
多处理器
基于指令流的数量和数据流的数量,将计算机体系结构分为SISD、SIMD、MISD和MIMD四类。
- 单指令流单数据流(SISD)结构,只有一个处理器一个存储器,处理器在一段时间内仅执行一条指令,按指令流规定的顺序串行执行指令流中的若干条指令,可以采用流水线技术,也可以设置多个功能部件使用多模块交叉方式的存储器
- 单指令流多数据流(SIMD)结构,一个指令流同时对多个数据流进行处理,一般称为数据级并行技术。这种计算机通常由一个指令控制部件、多个处理单元组成。每个单元有自己的地址寄存器,也就是都有不同的数据地址,因此可以有多种组织方式
- 多指令流单数据流(MISD)结构不存在
- 多指令流多数据流(MIMD)结构,同时执行多条指令分别处理多个不同的数据,MIMD分为多计算机系统和多处理器系统,前者每个节点有私有存储器和主存地址空间,且相互隔绝,需要消息传递(消息传递MIMD);后者共享地址空间,存取指令来访问所有存储器(共享存储MIMD)
其中SIMD是一种数据级并行模式,而MIMD是一种并行程度更高的线程级并行或线程级以上并行计算模式
向量处理器是SIMD的变体,是一种实现了直接操作一维数组(向量)指令集的CPU,将从存储器中收集的一组数据按顺序放到一组向量寄存器中,然后以流水化的方式对它们依次操作,最后将结果写回寄存器,适用于数值模拟等领域
硬件多线程
硬件实现的多线程为每个线程提供单独的通用寄存器组、单独的程序计数器等,线程的切换只需激活选中的寄存器,从而省略了与存储器数据交换的环节,提高效率
- 细粒度多线程,多个线程之间轮流交叉执行指令,多个线程之间的指令是不相关的,可以乱序并行执行,每个时钟周期都可以切换线程
- 粗粒度多线程,一个线程阻塞时才切换线程,流水线阻塞时,必须清除被阻塞的流水线,新线程的指令开始执行前需要重载流水线,切换开销更大
- 同时多线程SMT,实现指令级并行与线程级并行,在同一个时钟周期中,发射多个不同线程中的多条指令执行。例如intel的超线程就是SMT,单核中线程有自己的状态组件(需要芯片组、操作系统和应用软件的支持)
多核处理器
多个处理单元集成到单个CPU中,每个处理单元称为一个核,核一般都是对称的,并且共享主存储器,Cahe可独立可共用,因此多核属于共享存储的对称多处理器,可以实现真正的线程并行执行 具有共享的单一物理地址空间的多处理器被称为共享内存多处理器(SMP),可以通过存储器的共享变量实现通信,所有处理器都可以访问整个存储器,但可以通过虚拟地址空间独立运行程序
- 统一存储访问(UMA)多处理器,访问时间与哪个处理器提出访存请求及访问哪个字无关,分为基于总线、基于交叉开关网络和基于多级交换网络连接等几种处理器
- 非统一存储访问(NUMA)多处理器,访问请求直接有时间区别,处理器中不带高速缓存时,被称为NC-NUMA;处理器中带有一致性高速缓存时,被称为CC-NUMA
早期计算机的cpu通过北桥芯片统一访存,但随后cpu数量增加,总线告急,因此每个cpu都要设置独立的内存控制器,连接一部分内存(本地内存),访问非本地内存时再通过总线访问
在操作共享变量时需要进行同步机制,例如加锁
组合逻辑电路是具有一组输出和一组输入的非记忆性逻辑电路, 它的基本特点是任何时刻的输出信号状态仅取决于该时刻各个输入信号状态的组合,而与电路在输入信号作用前的状态无关。组合电路不含存储信号的记忆单元,输出与输入之间无反馈通路,信号是单向传输的。
时序逻辑电路中任意时刻的输出信号不仅和当时的输入信号有关,而且与电路原来的状态有关,这是时序逻辑电路在逻辑功能上的特点。因而时序逻辑电路必然包含存储记忆单元。
此外,组合逻辑电路没有统一的时钟控制,而时序逻辑电路则必须在时钟节拍下工作
- UMA构架由于所有CPU共享相同的内存,增加CPU路数会加大访存冲突,通常2或4路的性能最好,而NUMA理论上支持无限扩展
- 多核系统的Cache 一致性既包括Cache和内存之间的一致性,还包括各CPU的Cache之间的一致性,对内存同一位置的数据,即不同CPU的Cache不应该有不一致的内容
总线
概念
总线的定义 一组能为多个部件分时共享的公共信息传送线路
- 分时:同一时刻只允许有一个部件向总线发送信息。若系统中有多个部件,则它们只能分时地向总线发信息
- 共享:总线可以挂多个部件,部件交换信息可以用总线分时共享
总线上所连接的设备,按其对总线有无控制功能可分为主设备和从设备两种
- 主设备:获得总线控制权的设备
- 从设备:被主设备访问的设备,它只能响应从主设备发来的各种总线命令
分类:
- 片内总线,芯片内部的总线,如寄存器,ALU之间或者相互的连接
- 系统总线,各个功能部件的连接线
- 数据总线,双向传输,位数与机器字长和存储字长有关
- 地址总线,单向传输,用于访问主存和IO端口,位数与主存地址空间有关
- 控制总线,传输控制信息
- I/O总线,连接低速的IO设备,通过IO接口连接系统总线,如USB,PCI总线
- 通信总线,系统之间(包括非计算机的电子设备)的总线,也称外部总线
也有同步/异步,并行/串行的分类
结构(靠近CPU的总线速度较快):
- 单总线结构,CPU、主存、I/O设备(通过I/O接口)都挂在一组总线上,允许I/O设备之间、I/O设备与主存之间直接交换信息,结构简单,成本低
- 双总线结构,一条是主存总线,用于在CPU、主存和通道之间传送数据;另一条是I/O总线,用于在多个外部设备与通道之间传送数据;需要增加通道等硬件设备
- 三总线结构,主存总线(cpu与主存)、I/O总线(IO与cpu)和直接内存访问(DMA)总线(内存和高速外设);提高吞吐量,但任意时刻只能使用一种总线,效率较低
总线标准:国际上公布的互连各个模块的标准
- ISA(系统)
- EISA(拓展前者)
- VESA(视频)
- PCI(外接设备显卡声卡等)
- AGP(视频)
- PCI-E(取代PCI,AGP,以上四者都是局部总线)
- USB(IO)
- IDE/ATA(磁盘接口)
- SATA(硬盘)
性能指标:
- 传输周期,一次总线操作所需时间,包括申请,寻址,传输和结束
- 总线时钟周期,受到计算机时钟控制
- 总线工作频率,总线操作的频率,为总线周期倒数
- 总线时钟频率,与机器时钟频率相同
- 总线宽度(位宽),通常是数据总线根数
- 总线带宽,总线最大数据传输率,字节/秒,总线带宽= 总线工作频率x(总线宽度/8)
- 总线复用,一种信号线在不同时间传输不同信息
- 信号线数,三种总线的线数和
最主要性能指标为总线宽度、总线(工作)频率、总线带宽
总线带宽=总线宽度x总线频率
桥接器用于连接不同的总线,具有数据缓冲、转换和控制功能。
- 地址总线不仅可以指定主存单元,也可用来指定IO端口
- 地址总线是用于CPU到主存和I/O端口地址的单向总线,控制信息和状态信息也类似
- CPU的控制总线提供的控制信号包括时序信号、I/O设备和存储器的响应信号等
- PCI、EISA、ISA均是并行总线,USB是通用串行总线
- 突发(猝发)传输方式可以连续传送地址连续的数据,但需要先传一个地址
- USB是一种连接外部设备的I/O总线标准,属于设备总线,是设备和设备控制器之间的接口。而PCI、AGP、PCIE作为计算机系统的局部总线标准,通常用来连接主存、网卡、视频卡等
- PCI-Express总线采用串行数据包传输数据
总线事务与定时
总线事务:从请求总线到完成总线使用的操作序列
- 请求,主设备(cpu/dma)发出总线传输请求,获取总线控制权
- 仲裁,总线仲裁机构决定将下个周期的总线使用权交给某个申请者
- 寻址,主设备通过总线给出要访问的从设备地址和相关命令,启动从模块
- 传输,主从模块数据交互,分为寻址阶段、申请分配阶段、传输阶段
- 释放,主模块信息从系统总线上撤出,让出总线使用权
上升(下降)沿:数字电平从0(1)变为1(0)的一瞬间,可通过这两个信号规定总线连接设备操作的时间次序
突发(猝发)传送方式能够进行连续成组数据的传送,其寻址阶段发送的是连续数据单元的首地址,在传输阶段传送多个连续单元的数据,每个时钟周期可以传送一个字长的信息,但是不释放总线,直到一组数据全部传送完毕后,再释放总线
在某个总线周期内,总线上只有一个主设备控制总线,选择一个从设备与之进行通信(一对一),或对所有设备进行广播通信(一对多)
总线定时是指总线在双方交换数据的过程中需要时间上配合关系的控制,这种控制称为总线定时,其实质是一种协议或规则,主要有同步和异步两种基本定时方式。
- 同步定时方式,系统用统一的时钟信号协调发送接受方的传送定时关系,一个时钟周期构成总线周期,周期内发送接收方可以进行数据传送。速度快且控制逻辑简单,但可靠性交叉,适用于总线较短且部件存取时间相近的系统(高速部件会被拖累)
- 异步定时方式,把交换信息的两个部件或设备分为主设备和从设备,主设备提出交换信息的“请求”信号,经接口传送到从设备;从设备接到主设备的请求后,通过接口向主设备发出“回答”信号。没有固定周期,可靠性高,更复杂且低速,每个字符都要用开始位和停止位作为字符开始和结束的标志。根据“请求”和“回答”信号的撤销是否互锁,可分为:
- 不互锁,主设备请求后,一段时间没有接受则撤销,从设备也一样自动撤销
- 半互锁,请求必须在回答后才撤销,回答则可以自动撤销(隔一段时间后自动撤销“回答”信号)
- 全互锁,请求回答彼此都需要回复
- 分离式:
- 各模块均有权申请占用总线,包括接收方和发送方
- 采用同步方式通信,不等对方回答,每次发送都是单方向
- 各模块准备数据时,不占用总线
- 总线利用率提高,但控制复杂
半同步通信总线既保留了同步通信的特点,又能采用异步应答方式连接速度相差较大的设备。通过在异步总线中引入时钟信号,其就绪和应答等信号都在时钟的上升沿或下降沿有效,而不受其他时间的信号干扰。
例如从某个时钟开始,在每个时钟到来时,采样Wait信号,若无效,则说明数据未准备好,下个时钟到来时,再采样Wait信号,直到检测到有效再取数据
IO设备
IO接口
I/O接口(I/O控制器)是主机和外设之间的交接界面,通过接口可以实现主机和外设之间的信息交换
主要功能:
- 地址译码和设备选择,译码cpu送来的外设地址码,选择指定的设备
- 主机和外设的通信控制,协调不同工作速度,时序的外设和主机之间交换信息
- 数据缓冲,为了协调速度,接口需要用寄存器暂存部分数据
- 信号格式转换,电平,数据格式的转换
- 传送控制命令和状态信息,负责启动关闭,中断等信息的传送
基本结构:
I/O接口在主机侧通过I/O总线与内存、CPU相连。通过数据总线,在数据缓冲寄存器与内存或CPU的寄存器之间进行数据传送。同时接口和设备的状态信息被记录在状态寄存器中,通过数据线将状态信息送到CPU。CPU对外设的控制命令也通过数据线传送,一般将其送到I/O接口的控制寄存器。
接口中的地址线用于给出要访问的I/O接口中的寄存器的地址,它和读/写控制信号(通过控制线)一起被送到I/O接口的控制逻辑部件
接口中的I/O控制逻辑还要能对控制寄存器中的命令字进行译码,并将译码得到的控制信号通过外设界面控制逻辑送到外设,同时将数据缓冲寄存器的数据发送到外设或从外设接收数据到数据缓冲寄存器。另外,它还要具有收集外设状态到状态寄存器的功能。
对数据缓冲寄存器、状态/控制寄存器的访问操作是通过相应的指令来完成的,通常称这类指令为I/O指令,I/O指令只能在操作系统内核的底层I/O软件中使用,它们是一种特权指令
接口类型:
- 按数据传送方式分
- 并行接口(一个字/字节的所有位同时传送)
- 串行接口(一次传送一位)
- 主机控制方式分
- 程序查询接口
- 中断接口
- DMA接口
- 功能选择分
- 可编程接口
- 不可编程接口
IO端口:I/O端口是指接口电路中可被CPU直接访问的寄存器,主要有数据端口、状态端口和控制端口,若干端口加上相应的控制逻辑电路组成接口
通常,数据端口可RW,状态端口只能R,控制端口只能W
各个端口有自己的编号,对应一个端口地址,编址方式分为:
- 统一编址,存储器映射方式,将IO端口当做存储器单元分配地址,可以用统一访存指令访问。编址空间较大,不需要专用指令,但占用存储器地址,且执行较慢
- 独立编址,IO映射方式,需要专门的IO指令访问IO端口,IO地址空间和主存独立。更清晰,但控制逻辑更复杂
- I/O总线分为三类:数据线、控制线和地址线。数据缓冲寄存器和命令/状态寄存器的内容都是通过数据线来传送的;地址线用以传送与CPU交换数据的端口地址;而控制线用以给I/O端口发送读/写信号
- IO指令格式和其他通用指令相比有所不同
- 磁盘驱动器是由磁头、磁盘和读/写电路等组成的,也就是我们平常所说的磁盘本身
IO方式
常用的I/O方式有程序查询、程序中断、DMA和通道等
程序查询方式
信息交换的控制完全由CPU执行程序实现,程序查询方式接口中设置一个数据缓冲寄存器(数据端口)和一个设备状态寄存器(状态端口)
IO操作时,先发出询问信号,再根据设备状态决定传送时间
工作流程:
- cpu执行初始化程序,预置传送参数
- 向IO口发出命令字,启动设备
- 从外设接口读取状态
- cpu查询状态,直到就绪
- 传送数据
- 修改地址和计数器参数
- 若计数器不为0(传送未结束)则转3,否则结束
结构最简单,但cpu需要忙等待,与io串行工作,效率低
程序中断方式
cpu启动io流程后,继续工作,直到io发送中断请求,再用中断服务程序处理(IO准备数据过快的话,可能来不及取就数据溢出)
工作流程:
- 中断请求,一般每个中断源有中断请求标记触发器,置1为中断请求,触发器组成中断请求标记寄存器,可放置于cpu或中断源。请求分为可屏蔽(INTR线,关中断时不响应),不可屏蔽(NMI线),内部异常
- 当 IF=1 时,若 INTR 保持高电平,则在当前指令执行完毕后就进入中断响应周期
- NMI 中断不必检查 IF 标志位是否为 1,强制需要处理
- INTA:中断响应(interrupt acknowledge)信号,输出。响应 INTR 输入。该引脚常用来选通中断向量码以响应中断请求
- 中断响应判优,一般来说,不可屏蔽中断 > 内部异常(硬件故障 > 软件中断) > 可屏蔽中断;DMA > IO(高速设备>低速设备,输入设备>输出设备,实时设备>普通设备)
- 响应中断的条件
- 中断源有中断请求
- 开中断(异常和不可屏蔽中断不受限制)
- 指令执行完毕(异常不受此限制),只有这时cpu会查询中断信号
- 中断响应,中断服务程序由硬件直接实现的,称为中断隐指令(与指令系统的指令性质不同),隐指令引出中断服务程序
- 关中断
- 保存断点,一般是PC,PSW内容保存在栈或者特定寄存器
- 中断服务程序,根据中断源选择合适服务程序,将服务程序入口地址送入PC
- 中断向量,每个中断都有一个唯一的类型号,每个中断类型号都对应一个中断服务程序,其入口地址就是中断向量,一般中断向量表集中存于主存。(也可以软件查询法,使用向量法的中断称为向量中断)
- 中断处理过程,一般而言如下图,其中现场指的是用户可见的工作寄存器内容,图中如果不允许嵌套中断,中断服务前后的开关中断省去
若CPU在执行中断服务程序的过程中,又出现了新的更高优先级的中断请求,cpu暂停现行中断服务去处理新的中断,这种中断称为多重中断(中断嵌套)需要满足:
- 中断服务程序中提前设置开中断指令
- 优先级别高的中断源有权中断优先级别低的中断源
现代计算机一般使用中断屏蔽技术,每个中断源都有一个屏蔽触发器,1表示屏蔽该中断源的请求,0表示可以正常申请,所有屏蔽触发器组合在一起便构成一个屏蔽字寄存器,屏蔽字寄存器的内容称为屏蔽字。利用屏蔽技术可以动态调整优先级,否则处理和响应优先级相同(表示中断源自身的位置1)
屏蔽字就类似于官僚系统,可以屏蔽的(即寄存器中的1)越多,其优先级越高
DMA
在外设与内存之间开辟一条“直接数据通道”
适用于磁盘、显卡等高速设备大批量数据的传送,硬件开销较大,中断的作用仅限于故障和正常传送结束时的处理
- 主存和DMA接口之间有一条直接数据通路。IO访存无需经过cpu,与主机并行。
- 数据块传送时,主存地址的确定、传送数据的计数等都由硬件电路直接实现。
- 主存中要开辟专用缓冲区,及时供给和接收外设的数据
- 传送速度快,且传送前需要程序预处理,结束时需要通过中断进行后处理
组成: 对数据传送过程进行控制的硬件称为DMA控制器(DMA接口),控制器向cpu发出传送请求,响应后cpu让出整个系统总线,由DMA控制器接管总线传送数据
- 接受外设的dma请求,向cpu请求总线
- cpu发出总线响应信号后,dma接管总线
- 确定传送数据的地址与长度(由设备驱动程序设置传送参数)
- 规定数据传送方向,发送读写等控制信号进行传送
- 结束后向cpu报告
传送方式
- 停止cpu访存,与上文一致
- 周期挪用(窃取);IO请求时如果cpu正在访存,则等到存取周期结束;IO请求如果与cpu访存请求同时,则IO(优先级更高)挪用若干存取周期,传送一个数据就立刻释放总线
- DMA和cpu交替访存,CPU的工作周期比主存存取周期长时,可以将cpu周期分为dma和cpu分别的访存周期,分时控制
传送过程
- 预处理,CPU完成一些必要的准备工作。测试设备状态,设置传送方向,寄存器等,随后cpu执行原有程序,直到IO就绪请求DMA
- 数据传送,可以以单字节(或字)为基本单位,也可以以数据块为基本单位(DMA控制器用循环实现)
- 后处理,DMA控制器向CPU发送中断请求,CPU执行中断服务程序做DMA结束处理,包括校验数据是否正确,传送是否出错等
与中断的区别:
- 中断需要保护恢复现场;DMA方式不中断现行程序,无需保护现场,除了预处理和后处理不占用cpu
- cpu只在指令结束时响应中断;但任意周期结束时都可以响应DMA请求,即每个机器周期结束时都可以响应
- 中断需要cpu干预,DMA不需要且更加高效
- DMA请求优先级高于中断
- 中断可以处理异常,DMA只用于传送数据
- 中断通过程序层面传送数据,DMA则是硬件层
- 中断向量是中断服务程序的入口地址,中断向量地址是内存中存放中断向量的地址,即中断服务程序入口地址的地址
- 内部异常都是不可屏蔽的内中断,外部中断区分NMI,INTR
- cache等硬件错误不属于中断
- 浮点数上溢,表示超过了浮点数的表示范围,属于内中断(下溢是0不需要处理)
- CPU会在每个存储周期结束后检查是否有DMA请求
- 中断优先级由高至低为访管->程序性->重新启动
- 允许中断触发器置0表示关中断,在中断响应周期由硬件自动完成,即中断隐指令完成;恢复现场和屏蔽字时,由关中断指令完成
- 中断屏蔽标志的一种作用是实现中断升级,即改变中断处理完成的次序(中断响应次序由硬件排队电路决定)
- 与中断不同,DMA请求的响应时间可以发生在每个机器周期结束时,只要CPU不占用总线
- 指令寄存器IR和标志寄存器FR的输出信号会连到控制部件的输入端
- 关中断; 保存断点;识别中断源由硬件完成,现场保护恢复与开中断由中断服务完成
- 外部设备通常不能发出不可屏蔽中断
- CPU检测不到处理优先级更低的中断请求信号,检测到中断请求信号,则说明其处理优先级更高
杂项
透明性总结:
- 所有用户可见
- pc
- psw
- 通用寄存器(组)
- ACC
- 汇编程序员可见
- 中断字寄存器(相应优先级是硬件写死的,屏蔽字可以更改,置1表示屏蔽)
- 基址寄存器
- 变址寄存器
- 虚拟存储空间
- 所有用户不可见
- MDR
- MAR
- IR
- 微程序相关寄存器
- Cache
- I/O总线分为三类:数据线、控制线和地址线。数据缓冲寄存器和命令/状态寄存器的内容都是通过数据线来传送的;地址线用以传送与CPU交换数据的端口地址;而控制线用以给I/O端口发送读/写信号