# CPU
## CPU的功能和基本结构
## 指令执行过程
## 数据通路的功能和基本结构
## 控制器的功能和工作原理
## 异常和中断机制
- 基本概念
- 分类
- 检测和响应
## 指令流水线
- 基本概念
- 基本实现
- 结构冒险、数据冒险和控制冒险
- 超标量和动态流水线的基本概念
## 多处理器基本概念
- SISD、SIMD、MIMD、向量处理器的基本概念
- 硬件多线程的概念
- 多核处理器的基本概念
- 共享内存多处理器的概念
## 总线和输入/输出系统
### 总线
- 基本概念
- 组成及性能指标
- 事务和定时
### I/O接口
- 功能和基本结构
- 端口及其编址
### I/O方式
- 程序查询方式
- 程序中断方式
- DMA方式
中央处理器
1 - 功能和结构
CPU 基本结构
CPU 的内部结构由 BIU 和 EU 两部分构成,简单而言,BIU 负责读指令,EU 负责执行指令。两个组成部分的具体功能如下:
- BIU(Bus Interface Unit,总线接口单元):
- 主要功能
- 从内存中取指令,并将其存储在指令队列中。
- 计算存储器地址,并控制总线进行数据传输。
- 组成:
- 指令队列:用于存储从内存中预取的指令。
- 特殊寄存器
- 指令指针寄存器(IP):存储下一条要执行的指令地址。
- 指令寄存器(IR),存储当前正在执行的指令
- 内存地址寄存器(MAR),存储内存需要读取的地址
- 内存数据寄存器(MDR),存储内存读取的数据单元
- 段寄存器(Segment Registers)
- 主要功能
- EU(Execution Unit,执行单元):
- 主要功能:
- 从指令队列取出指令,进行译码。
- 执行指令,包含算术运算、数据传输等。
- 组成:
- 算术逻辑单元(ALU),用于执行算术和逻辑运算,例如加法、减法、逻辑与、逻辑或等。
- 通用寄存器: 包括 AX、BX、CX、DX、SI、DI、BP 和 SP 等寄存器,用于存储数据和地址。
- 控制单元(CU, Control Unit),负责取指令和解码指令、生成控制信号、协调 CPU 中指令的执行过程。
- 主要功能:
提示
寄存器的英文全称:
- IP: Instruction Pointer
- IR: Instruction Register
- MAR: Memory Address Register
- MDR: Memory Data Register
BIU 和 EU 并行工作,以此提高 CPU 的效率。例如,当 EU 执行一条指令时,BIU 可以同时从内存中预取下一条指令,并将其存储在指令队列中。
寄存器
寄存器类型
- 通用寄存器(General-Purpose Registers):
AX
寄存器:累加器(Accumulator),用于执行算术和逻辑运算。BX
寄存器:基址寄存器(Base Register),通常用于存储内存地址。CX
寄存器:计数寄存器(Counter Register),用于循环计数和移位操作。DX
寄存器:数据寄存器(Data Register),用于输入/输出操作和大整数运算。
- 段寄存器(Segment Registers):
CS(Code Segment)
寄存器:代码段寄存器,存储指向代码段的地址。DS(Data Segment)
寄存器:数据段寄存器,存储指向数据段的地址。ES(Extra Segment)
寄存器:附加数据段寄存器,通常用于数据访问。SS(Stack Segment)
寄存器:堆栈段寄存器,存储指向堆栈段的地址。
- 指针寄存器(Pointer Registers):
SI
寄存器:源变址寄存器,通常用于数据传送操作。DI
寄存器:目的变址寄存器,也通常用于数据传送操作。SP
寄存器:堆栈指针寄存器,用于堆栈操作。BP
寄存器:堆栈基址寄存器,通常用于堆栈操作。
- 附加寄存器(Extra Registers):
IP(Instruction Pointer)
寄存器:指令指针寄存器,存储当前执行指令的偏移地址。FLAGS
寄存器:标志寄存器,存储有关条件和状态的信息,例如进位、零标志、溢出等。
哪些寄存器是程序员可见的:
通用寄存器、PC 可见
MAR、MDR、IR 不可见
标志寄存器
什么时候会被设置?
标志寄存器主要有两个功能:
- 条件标志:保存指令执行结果的状态。在执行条件分支、算数和逻辑、比较或移位指令后,条件标志都会被设置。
- 控制标志:控制指令执行的行为
条件标志(conditional flags)
OF (Overflow flag)
:溢出标志。- 当有符号整数运算的结果太大而无法适应目标寄存器时,OF 标志会设置为 1,表示发生了溢出。
SF (Sign flag)
:符号标志。- 根据操作结果的符号位来设置,如果结果为负数,则 SF 被设置为 1,否则为 0。
ZF (Zero flag)
:零标志。- 当操作结果为零时,ZF 标志被设置为 1,否则为 0。
AF (Auxiliary carry flag)
:辅助进位标志。- 通常用于 BCD(二进制编码十进制)算术运算,指示低四位的进位。
PF (Parityh flag)
:奇偶校验标志。- 根据结果中二进制位 1 的个数是奇数还是偶数,设置 PF 标志。奇数个 1 则 PF 为 1,偶数个 1 则 PF 为 0。
CF (Carry flag)
:进位标志。- 当无符号整数运算的结果超出了目标寄存器的位数,CF 标志被设置为 1,表示发生了进位。
控制标志(control flags)
TF(Trap flag)
- 控制单步执行。
- 当 TF 被设置为 1 时,CPU 将进入单步执行模式。在单步执行模式下,每执行一条指令后,CPU 将引发一个单步中断,允许程序员逐条调试程序。
IF(Interrupt flag)
- 控制中断处理
- 当 IF 被设置为 1 时,CPU 允许中断请求。如果 IF 为 0,CPU 将禁止所有中断请求,无论是外部硬件中断还是软件中断。
DF(Direction flag)
- 字符串操作的标志位。
- 当 DF 被设置为 1 时,字符串操作(如 MOVS、LODS、STOS)在内存中向高地址方向移动。这通常用于从高地址向低地址扫描字符串。当 DF 被清除为 0 时,字符串操作在内存中向低地址方向移动。这通常用于从低地址向高地址扫描字符串。
2 - 控制器
控制器是计算机系统的指挥中心,控制器的主要功能有:
- 指令解码:CPU从存储器取出一个指令后,控制器负责解码这个指令,以确定要执行的操作和涉及的操作数。
- 生成控制信号:基于解码的指令,控制器生成一系列的控制信号,这些信号会驱动其他计算机部分(如算术逻辑单元、寄存器和存储器)按预期执行相应的操作。
- 指令执行的顺序和时序:通过先后发出不同的控制信号,确保指令的逻辑正确被执行,
根据控制器产生微操作控制信号方式的不同,控制器可以分为硬布线控制器和微程序控制器。
控制信号
概念
控制信号是由控制单元(Control Unit)生成和发出的电信号,这些信号用于指挥CPU内部的各种操作。例如,控制信号可以指示算术逻辑单元(ALU)执行加法还是减法,或者指示寄存器进行读写操作。
类型
其实控制信号的种类很多,但就目前阶段而言,会考察的可以被总结为三类控制信号:
- 读写信号:对内存或IO设备进行读写,比如
MemR
和MemW
- 寄存器选择信号:选择特定的寄存器进行读写操作,比如
PCin
和PCout
- 操作码信号:示算术逻辑单元(ALU)执行哪种运算,如加法、减法、与、或等。
指令的不同执行阶段对应的控制信号
指令的执行包含取指、译码、执行、写回阶段,在这四个阶段中控制单元会发出不同的控制信号,以实现指令的执行。
以指令ADD R0, (R1)
为例,说明一下指令执行阶段四个阶段的控制信号。
取指和译码阶段
时钟 | 功能 | 控制信号 | 解释 |
---|---|---|---|
C1 | MAR ← (PC) | PCout , MARin | 从 PC 中读取指令地址至 MAR 中 |
C2 | MDR ← M(MAR) | MemR , MDRin | 存储器从MAR地址所在的内存单元读取数据 并加载到MDR中 |
C3 | MUXop ← PCIncr | PCIncr | 在二路选择器中生成值 1 添加入 ALU 的一端 |
C4 | T2 ← PC + 1 | MARout , T2in , Add | ALU 计算下一条指令的地址 |
C5 | PC ← T2 | T2out , PCin | 将计算得到的地址加载进 PC 中 |
C6 | 指令译码 | 无 | 由指令译码器件完成 |
执行和写回阶段
时钟 | 功能 | 控制信号 | 解释 |
---|---|---|---|
C7 | MAR ← R1 | R1out ,MARin | 将 R1 中的内容加载进 MAR |
C8 | MDR ← M(MAR) | MemR , MDRin | 存储器从MAR地址所在的内存单元读取数据 并加载到MDR中 |
C9 | T1 ← R0 | R0out , T1in | 将 R0 的内容存储在暂存器 T1 |
C10 | T2 ← MDR + T1 | MDRout , MUXop ,Add , T2in | 将MDR 的内容存储进入ALU 另一个入口执行加法操作 并将结果存储进入 T2 |
C11 | R0 ← T2 | T2out , R0in | 将计算结果写回 R0 |
为什么需要暂存器T1?
采用了单数据总线的系统,无法在一个时钟周期同时将两个不同的数字同时添加到ALU的两端,在一个时钟周期内ALU两端会接受到相同的数据,所以必须要在当前时钟周期暂存一个数据,在下一个时钟周期再向ALU添加另一个数据。
硬布线控制器
定义:硬布线控制器是通过组合逻辑电路来实现的,通常使用逻辑门、多路复用器、解码器等组合电路元件。
特点:
- 性能:因为是硬件实现,所以通常速度较快。
- 固定功能:一旦设计和实现完成,修改它就比较困难,需要改变物理电路。
- 设计复杂性:对于复杂的控制逻辑,硬布线控制器可能会变得非常复杂,难以设计和验证。
微程序控制器
定义:微程序控制器基于存储的微指令集来实现控制逻辑。它使用一块称为“控制存储器”或“微指令存储器”的特殊存储器来存储微指令。每一个微指令定义了一系列的控制信号。
特点:
- 灵活性:由于控制逻辑是存储在存储器中的,所以更改控制逻辑只需要更改存储的微指令,而无需更改硬件。
- 简化设计:对于复杂的控制逻辑,使用微指令可能会简化设计和验证过程。
- 性能:通常比硬布线控制器慢,因为它需要从控制存储器中读取微指令。
- 易于修改和扩展:添加新的指令或修改现有的指令相对容易。
指令、微指令、微命令
微命令是计算机硬件控制的基础指令,用于控制某些硬件单元完成某种操作。
一条机器指令对应一个微程序,一个微程序由数条微指令构成,每个微指令可以包含数个微命令。
微指令编码方式
- 直接编码方式
微指令中的微命令字段中每位都代表一个微命令。
- 字段直接编码方式
将微指令的微命令字段分为若干小段,把互斥行微命令组合在同一字段中,把相容性微命令组合在不同字段中,每个字段独立编码,每种编码代表一个微命令且各字段编码含义单独定义。
3 - 异常与中断
异常
在CPU中,异常是指在执行程序时遇到的非常规或意外情况,需要操作系统介入以调整、中断或改变程序的正常执行流程。CPU会使用异常处理机制来处理这些情况。
类型
- 除法错误(Division Error)
- 触发条件:程序尝试除以零或执行其他非法的除法操作时触发。
- 处理:通常会中断程序运行,并可能通过操作系统给出错误信息。
- 缺页异常(Page Fault)
- 触发条件:程序尝试访问的内存页不在物理内存中时触发。
- 处理:操作系统将相应的内存页从磁盘加载到物理内存中,并更新页表。
- 无效指令(Invalid Instruction)
- 触发条件:CPU遇到未被定义或不可执行的指令时触发。
- 处理:通常会中断程序的执行,并可能给出错误信息。
- 保护错误(Protection Fault)
- 触发条件:程序尝试执行一些不被允许的操作,如访问受保护的内存区域或执行特权指令时触发。
- 处理:通常会中断程序的执行,并可能给出错误信息。
- 机器检查(Machine Check)
- 触发条件:硬件错误或故障,如内存错误、总线错误等。
- 处理:取决于具体硬件和配置,可能包括中断程序、记录错误信息、尝试纠正错误等。
- 浮点异常(Floating-Point Exception)
- 触发条件:浮点运算错误,如溢出、下溢、除以零、无效操作等。
- 处理:可能包括提供一个近似结果、设置状态标志、中断程序等。
自陷
在CPU和操作系统的上下文中,“自陷”(也称为陷阱,trap)是一种机制,其中程序执行中的某些条件会导致处理器自动执行一个异常或中断的响应例程。自陷通常是由以下原因引起的:
- 异常:程序执行中出现了错误条件,例如除以零、访问非法内存地址、执行非法指令等。
- 系统调用:程序请求操作系统服务,例如文件操作、进程创建、网络通信等。在大多数系统中,这通过执行一个特定的指令(如syscall在x86架构上)来完成,它会触发自陷并进入内核模式。
- 断点调试:在软件开发的调试过程中,可以设置断点以在特定的程序点停止执行,允许开发者检查程序状态。当程序达到断点时,会触发自陷。
自陷流程与外中断处理流程类似:
- 处理器检测到一个自陷条件。
- 当前的程序执行被中断,处理器状态(如程序计数器、寄存器等)被保存。
- 处理器切换到内核模式(如果它之前在用户模式下运行),这是一种更高的特权级别,允许执行操作系统代码。
- 控制权转移到预定的自陷处理程序或中断处理程序。这通常是操作系统内核的一部分,能够处理异常或执行系统调用。
- 自陷处理程序执行必要的服务或处理异常。
- 一旦自陷处理完成,程序可以返回到自陷发生前的状态并继续执行,或者如果出现了无法恢复的错误,程序可能会被终止。
陷阱指令(trap instruction)是一种特殊的指令,用于故意中断当前的程序流,并将控制权转移给操作系统。这是一种由程序员显式请求的自陷(trap),通常用于执行系统调用、启动调试操作或其他由操作系统内核提供的服务。
中断
中断概念
- 中断请求(IRQ,Interrupt ReQuest):
- 外部设备通过中断请求线向CPU发送中断请求,每个设备通常有一个特定的IRQ号码。
- 中断控制器(PIC, Prgrammable Interrupt Controller):
- 包含一个中断控制器芯片用于集中处理和管理中断请求。这个控制器接收来自多个设备的中断请求,并将它们传递给 CPU。
- 中断向量:
- 中断服务程序的入口地址,是中断向量表中的一个表项。
- 中断服务程序(ISR,Interrupt Service Routine):
- 一旦中断向量被确定,处理器会跳转到相应的中断服务例程,即中断处理程序。
- 中断向量表:
- 一个数组或表格,包含了各种中断类型的中断处理程序的起始地址,每个中断向量的值对应于相应中断处理程序的地址。
分类
按中断类型
- 外部中断(External Interrupt):
- 触发来源:外部设备或外部事件触发,如输入设备、时钟、外部信号等。
- 响应:CPU响应外部事件,执行相应的中断处理程序。
- 内部中断(Internal Interrupt):
- 触发来源:程序或CPU内部状态触发,如异常、错误等。
- 响应:CPU根据内部条件触发中断,执行特定的中断处理程序。
- 软件中断(Software Interrupt):
- 触发来源:软件或操作系统指令触发,常用于实现系统调用。
- 响应:CPU执行一个特定的中断处理程序来响应软件的请求。
按是否可屏蔽
- 可屏蔽中断:可屏蔽中断是可以被禁用或屏蔽的中断。处理器可以通过设置特定的标志或寄存器来忽略这类中断。
- 不可屏蔽中断:不可屏蔽中断是不能被禁用或屏蔽的中断。这类中断通常与系统的关键和紧急事件相关。
中断和异常的区别:
异常发生在CPU内部,在一般的分类方法中可以被看为中断类型的一种(内中断),但是在有的书上将中断和异常这两个概念区分了开来:
- 异常代表CPU执行指令时的意外事件
- 中断代表来自CPU外部、与CPU执行指令无关的事件引起的中断
在这里注意一下即可,面对题目可以灵活分辨即可
中断处理流程
4 - 指令流水线
指令执行的五个阶段
- 取指令(IF - Instruction Fetch): 从内存中取出指令。
- 指令译码(ID - Instruction Decode): 解析指令,确定其类型和操作数。
- 执行(EX - Execute): 执行指令,进行算数运算和逻辑运算等。
- 内存访问(MEM - Memory Access): 访问内存,读取或存储数据。
- 写回(WB - Write Back): 将执行结果写回到寄存器或内存。
指令流水线的基本概念
将指令执行的多个阶段由不同的硬件单独执行,各个阶段可以并行执行。这样,虽然每条指令的执行时间没有缩短,但是CPU的吞吐量得到了提升,也就是说,每单位时间内,CPU可以执行更多的指令。
流水线的冒险和处理
结构冒险
含义
结构冒险是由于CPU的硬件资源有限而引起的。当两条或多条指令需要使用同一硬件资源时,就会发生结构冒险。
处理方法
- 资源重复:增加硬件资源的数量,例如增加ALU或内存的端口数量。
- 流水线阶段调度:通过调整流水线的执行顺序或延迟某些指令的执行来避免冒险。
例子
// 如果CPU只有一个内存端口,那么I1和I2不能在同一个周期访问内存,这就产生了结构冒险。
I1: LOAD R1, 0(R2) // 将内存地址R2+0的值加载到寄存器R1
I2: STORE R3, 4(R4) // 将寄存器R3的值存储到内存地址R4+4
数据冒险
含义
数据冒险是由指令之间的依赖性引起的。一条指令可能需要使用另一条指令的结果,如果这些指令过早地进入流水线,它们可能会尝试在数据准备好之前使用数据。
数据冒险可以分为三类:
- 写后读(RAW, Read After Write):在一条指令尝试读取一个数据项的值时,而这个数据项的值还没有被前一条指令写入。
- 读后写(WAR, Write After Read):一条指令尝试写入一个数据项的值时,而这个数据项的值还没有被后一条指令读取。
- 写后写(WAW, Write After Write):两条指令尝试写入同一个数据项的情况,如果这两条指令的执行顺序不当,可能会导致不一致的结果。
处理方法
- 流水线停顿(Pipeline Stall):暂停流水线直到数据准备好。
- 重新排序指令(Instruction Reordering):编译器在编译时对指令进行重新排序,以减少数据冒险。
- 数据前推(Data Forwarding):设置相关专用通路,直接将前一条指令的结果传递给需要它的下一条指令,不等结果写回寄存器。
例子
下述代码给出了数据冒险的三种情况:
// RAW
I1: ADD R1, R2, R3 // R1 = R2 + R3
I2: SUB R4, R1, R5 // R4 = R1 - R5
// WAR
I1: LOAD R1, 0(R2) // R1 = Memory[R2+0]
I2: STORE R3, 0(R2) // Memory[R2+0] = R3
// WAW
I1: MUL R1, R2, R3 // R1 = R2 * R3
I2: ADD R1, R4, R5 // R1 = R4 + R5
高级语言一条赋值语句被汇编微如下四条指令:
I1 LOAD R1, [a]
I2 LOAD R2, [b]
I3 ADD R1, R2
I4 STORE R1, [x]
四条指令对应的流水线执行如下图所示:
其中 I3
和 I1
之间存在 WAW 数据冒险,I3
和 I2
之间存在 RAW 数据冒险,I4
和 I3
之间存在 WAR数据冒险,所以 I3
必须等待 I1, I2
执行完才能进行后续操作,
I4
必须等待 I3
执行完才能进行后续操作。
控制冒险
含义
控制冒险是由分支和跳转指令引起的。因为CPU需要在执行分支和跳转指令后,才能知道下一条要执行的指令在哪里,这导致了流水线的暂停或者无效的指令进入流水线。
处理方法
- 预测不跳转(Predict Not Taken):预测每个分支都不会被采取,当分支被采取时,取消流水线中的指令并从正确的位置重新开始。
- 预测跳转(Predict Taken):预测每个分支都会被采取,对预测错误的情况进行修正。
- 延迟分支(Delayed Branch):编译器或处理器对代码进行优化,将分支指令后的一些不依赖于分支结果的指令先执行,从而减少因分支预测错误造成的开销。
实例
// 直到I1被执行,我们都不知道接下来是执行I2还是跳转到I3
I1: BEQ R1, R2, Label // 如果R1等于R2,则跳转到Label
I2: ADD R3, R4, R5 // R3 = R4 + R5
I3: Label: MUL R6, R7, R8 // R6 = R7 * R8
5 - 多核处理器
SISD, SIMD, MIMD, 向量处理机
- SISD (Single Instruction stream, Single Data stream)
- 定义:一个指令流和一个数据流在单一处理器上顺序执行。这种架构中的每个操作指令都在一个数据上执行。
- 特点:简单、易于管理,但处理能力有限。
- SIMD (Single Instruction stream, Multiple Data streams)
- 定义:一个指令在多个数据上并行执行。这种架构用于执行重复的数据操作,特别适用于图形处理和科学计算。
- 特点:能高效处理大量数据,尤其在图像、音频和视频处理中表现出色。
- MIMD (Multiple Instruction streams, Multiple Data streams)
- 定义:多个处理器或多核处理器并行执行不同的指令序列,每个指令序列作用在不同的数据流上。这种架构用于多任务和并行处理环境。
- 特点:灵活、强大,能处理多任务和复杂的并行处理问题。
- 向量处理机 (Vector Processor)
- 定义:使用向量寄存器来存储数据,并能在一个指令中处理整个向量数据。适用于执行大量重复和并行操作的科学和工程计算。
- 特点:高性能,尤其在科学、工程和图形处理任务中表现出色。
多核处理器
现代一个CPU可以多个物理核心,一个物理核心可以使用超线程技术来实现多个逻辑核心。比如4核8线程的处理器,就是有4个物理核心,每个物理核心对应两个逻辑核心。
物理核心(Physical Cores):物理核心是处理器芯片上的实际硬件核心,它们能够独立执行指令和处理任务。一个物理核心可以看作是一个完整的处理单元,具有自己的寄存器、执行单元以及缓存。在4核心的处理器中,有四个物理核心。
硬件多线程
超线程技术的核心思想是将一个物理核心模拟成多个逻辑核心(线程),从而在同一时间内执行多个线程。每个逻辑核心都拥有自己的寄存器集合和执行单元,这些逻辑核心之间共享物理核心的资源,如缓存和执行单元。
共享内存多处理机
共享内存多处理机是一种计算机架构,其中多个处理器可以访问同一块物理内存。这样的架构允许处理器之间通过内存共享数据,从而实现并行处理和任务协同。
共享内存多处理机系统提供了一种有效的并行处理和数据共享机制,但也带来了同步、数据一致性和扩展性等方面的挑战。需要根据特定的应用和性能需求来选择和优化共享内存多处理机系统。