关于我

中央处理器

第五章_中央处理器

5.1 CPU 的功能和基本结构

本小节思维导图如下(挺杂乱的): 思维导图 CPU 内部分为运算器和控制器:

  1. 运算器: 运算器
  2. 控制器: 注意别把微操作信号发生器当做 CU 了,CU 比它大得多。 控制器

最后贴出一张 CPU 总的结构图: CPU 总的结构图 注意:三态门可以用 MUX(多路选择器)进行替代。

而不同寄存器对汇编语言程序员的不同透明度(透明为不可修改)需要进行区分:

寄存器 对汇编语言程序员 说明
通用寄存器 不透明(可见) 汇编指令可以直接指定,如 R1、R2
PC(程序计数器) 不透明(可见) 程序员通常能通过跳转、调用等指令间接改变,但一般不能像普通寄存器一样随意读写
专用地址寄存器 不透明(可见) 基址寄存器、变址寄存器、堆栈指针等
PSW/标志寄存器 可见/部分透明 用户程序不能进行直接修改,只能进行读取
IR(指令寄存器) 透明(不可见) 保存当前指令,程序员不能直接用汇编指令读写
MAR(存储器地址寄存器) 透明(不可见) CPU 内部用于给主存提供地址
MDR(存储器数据寄存器) 透明(不可见) CPU 与主存交换数据的内部寄存器
页表基址寄存器(PTBR) 透明(不可见) 保存当前页表的起始地址

5.2 指令执行过程

本小节思维导图如下: 思维导图

5.2.1 指令周期概念补充

早期计算机采用“机器周期-节拍-脉冲”三级时序系统。指令周期、机器周期和时钟周期 的区别如下图所示: 指令周期、机器周期和节拍 值得注意的是,不同指令的机器周期数是可以不等的,每个机器周期内的节拍数也可以是不相等的。如下图所示: 现代处理器已经大幅度简化时序结构,“机器周期”这一概念逐渐淡化。CPU 内部由统一的系统时钟直接驱动,一个时钟周期即对应一个节拍,绝大多数指令可在若干时钟周期内高效完成。(不用深究机器周期的概念)

5.2.2 指令周期流程

不难看出,指令周期其实不止取指周期和执行周期,可能含有四个周期,将其用流程图表示如下: 指令周期流程 关于指令周期的每个机器周期执行的具体过程需要掌握,如下所示:

  1. 取指周期: 取指周期
  2. 间址周期: 间址周期
  3. 执行周期: 每条指令的执行过程不同,不方便讲述。
  4. 中断周期: 注意:中断周期是 CPU 响应外部中断时在指令周期末尾插入的控制过程,用于保存断点并转入中断服务程序,与汇编语言中的函数调用(call / ret)机制无关。 中断周期

5.2.3 指令执行方案

指令执行方案 单周期处理器 中,所有指令都在一个时钟周期内完成,因此其指令周期为一个时钟周期(CPI=1)。

多周期处理器 中,不同指令占用不同数量的时钟周期,平均 CPI 通常大于 1。

流水线处理器 中,采用指令级并行策略,理想情况下 CPI = 1。

注意:时钟周期的具体数值可以由硬件设计者确定,并不是说 CPI 越小就越快。

5.3 数据通路

数据通路是指 指令执行过程中所经过的路径,包括路径上的部件。ALU、通用寄存器、状态寄存器、异常和中断处理等都是指令执行过程中数据流经的部件。

5.3.1 数据通路的组成

数据通路的基本构成元件可分为 组合逻辑元件 和 时序逻辑元件 两大类:

类型 核心特点 常见部件
组合(操作)逻辑部件 输入一变,输出随之变化;不保存状态 ALU、加法器、译码器、多路选择器、比较器、移位器
时序(状态)逻辑部件 能够保存状态,输出与当前输入及过去状态有关 各种寄存器、PC、IR、MAR、MDR、通用寄存器、状态/标志寄存器

5.3.2 数据通路的分类

5.3.2.1 按部件链接方式划分

数据通路按部件链接方式分为:

  1. CPU 内部总线:单总线、多总线。
  2. 专用数据通路。

单总线结构: 单总线数据通路结构简洁,所有数据传输共享一条内部总线,同一时刻仅允许一个部件向总线输出数据,导致操作需要分步进行。

本小节在考研中就主要考察一个指令的具体操作,CPU 内部的数据传输一般就分为三种,如下图所示: 一个指令的具体操作 通过一个例题来具体熟悉: 题目

专用数据通路: 专用数据通路是 CPU 中各功能部件之间采用固定的、专门的数据传送线路进行连接的数据通路结构。如下图所示: 专用数据通路 通过一个例题来具体熟悉: 例题

5.3.2.2 按时序组织方式划分

  1. 单周期数据通路 在单周期数据通路中,每条指令的所有操作(取指、译码、执行、访存、写回等)都在一个时钟周期内完成。 时钟周期长度由最慢的指令决定。

  2. 多周期数据通路 多周期数据通路将一条指令的执行划分为多个阶段,每个阶段在一个时钟周期内完成。典型阶段包括取指、译码与读寄存器、执行 / 地址计算、访存、写回等。

  3. 流水线数据通路 流水线数据通路将指令执行过程分解为若干独立、可重叠的阶段,不同指令在不同阶段并发推进。每个阶段由专用功能部件完成,并通过流水段寄存器隔离和传递中间结果。 特点是时钟周期长度由最长阶段决定;理想情况下,每个周期可以完成一条指令。

注意: 单周期处理器(CPI = 1)不能采用单总线结构的数据通路,因为单总线将所有寄存器都连接到一条公共总线上,一个时钟周期内只允许一次操作,无法完成一条指令的所有操作。

5.4 控制器的功能和基本结构

说一句话,在考研中,所有的底层硬件其实只需要知道控制流程,不用知道电路如何真正驱动控制流程。 例如:

  • 门级电路如何实现
  • 控制信号具体时序
  • 晶体管级实现
  • 电平变化传播
  • setup/hold
  • 时钟树

这些已经偏 CPU设计 / 数字IC / 体系结构了。

5.4.1 硬布线控制器

硬布线控制器由复杂的组合逻辑电路和触发器构成,也称 组合逻辑控制器。

首先我们需要知道,按照老版本的时序系统,一个指令分为多个机器周期(取指、间址、执行、中断),而每一个机器周期又分为多个节拍对应的微操作。如下图所示: 注意:一个节拍内可以并行完成多个“相容”的微操作。 老版本的时序系统 而 控制单元 CU 总观如图所示: 控制单元总观 有了上面的基础,我们显然能够想出,在 CU 内部,通过对 指令操作码、目前的机器周期、节拍信号、机器状态条件 进行逻辑电路设计,CU 就能判断现在应该执行什么微命令。如下图所示:


接下来当然面临的就是 硬布线控制器的设计问题: 设计步骤:

  1. 分析每个阶段的微操作序列(取值、间址、执行、中断 四个阶段)。(即确定哪些指令在什么阶段、在什么条件下会使用到的微操作)。
  2. 选择 CPU 的控制方式,(即采用定长机器周期还是不定长机器周期?每个机器周期安排几个节拍?),这里讲述假设采用同步控制方式(定长机器周期),一个机器周期内安排 3 个节拍。
  3. 安排微操作时序,(即如何用 3 个节拍完成整个机器周期内的所有微操作?)。
  4. 电路设计,(即确定每个微操作命令的逻辑表达式,并用电路实现)。
    1. 列出操作时间表
    2. 写出微操作命令的最简表达式
    3. 画出逻辑图

关于 步骤一: 步骤一 关于 步骤三: 步骤三取指周期 步骤三间址周期 步骤三执行周期 关于 步骤四: 理解步骤四,基本就能理解整个设计思路: 由于不同指令的执行周期对应不同的微命令,每个机器周期每个节拍也不同,所以将其列成了一张很长的表。 操作时间表 根据上面这张表,我们就能轻松的设计出微命令对应的逻辑表达式,从而设计出逻辑电路啦! 例子 画逻辑图参考上面那张图。

5.4.2 微程序控制器

本节思维导图如下: 思维导图

5.4.2.1 微程序控制器基本结构

本小节思维导图如下: 思维导图 首先明确一下 微程序、微指令、微命令/微操作 这之间的区别,如下图所示:

概念 是什么 例子
指令 程序员看到的、CPU要执行的一条机器指令 ADD R1,R2
微指令 CPU内部控制器在一个微周期发出的一组微命令(控制信号) R1out = 1、Yin = 1、R2out = 1、ALU_ADD = 1、Zin = 1
微命令 一个具体的 控制信号,控制数据通路完成某个动作 R1out = 1、Yin = 1
微操作 在微命令控制下,数据通路实际完成的基本操作 R1 → Y

微程序、微指令、微命令/微操作 微程序控制器的基本结构 如下图所示,其实可以看成是一个 CPU 内部又套了一个更小、更简单的 CPU: 特别注意控制存储器 CM,微程序就存储在其中。 微程序控制器的基本结构

5.4.2.2 微程序控制器工作过程

关于微程序控制器的工作过程:

  1. 执行指令公共操作: 系统启动或每条指令执行完毕后,将取指微程序的入口地址(通常为 CM 的 0 号单元)送入 uPC。随后,从 CM 中读取首条取指微指令并送入 uIR。完成取指微程序 ,

    系统启动时,会设置 PC 的值,这段公共微程序根据 PC 的值取指放入 IR,(PC->MAR->M(MAR)->MDR->IR)并且 PC + “1”。 (注意:题目中说一条指令对应的微指令通常不包括这个公共微指令)。

  2. 生成当前指令的微程序入口地址: 根据 IR 中机器指令的操作码,通过微地址形成部件产生对应微程序的起始微地址,并送入 uPC。

  3. 顺序执行微程序: 从 CM 逐条读取微指令,送入 uIR 并执行,直至该微程序执行完毕。

  4. 返回循环: 当前机器指令对应的微程序执行结束后,控制器自动转移回取指微程序的入口(步骤1),重新开始处理下一条机器指令。整个流程不断循环,直至整个程序执行完毕。

值得注意的是:控制存储器(CM)中的

  1. 微程序总数 = 支持的机器指令条数 + 公共微程序数(如取指、间址、中断等)。
  2. 微指令总数 = 支持的机器指令条数*机器指令平均指令条数 + 公共指令数

如下图所示: 微程序控制器的工作原理 关于微程序控制器的一些选择题常考点需要进行说明: 选择题常考点

5.4.2.3 微指令地址形成方式

  1. 增量方式(计数器方式):下条微地址由微程序计数器(uPC)自动加 1 生成,适用于微程序中的顺序执行段。
  2. 断定方式(下地址字段方式):在当前微指令中显式指定下条微地址。上方所有的微程序控制器图示都采用断定方式,其微指令包含下地址字段,可直接给出下条微地址。

5.4.2.4 微指令编码方式与格式

微指令的编码方式 即为微指令操作码的格式:

  1. 直接编码方式: 直接编码方式无须译码。微指令的操作控制字段中,每一位直接对应一个微命令(比如控制某通路的三态门开合)。设计微指令时,若需发出某个微命令,只需将对应位设为 1,否则设为 0。每个微命令独立控制数据通路中的一个微操作。
  2. 字段直接编码方式:字段直接编码将操作控制字段划分为若干字段。互斥性微命令被归入同一字段,相容性微命令则分配到不同字段。每个字段独立编码,经 译码 后在其所属的互斥微命令集中激活一个微命令。
  3. 字段间接编码方式(了解):字段间接编码进一步压缩微指令长度。其基本思想是:某个微命令字段的实际含义,由另一个字段的编码共同决定。例如,字段 A 的编码 001 本身无固定意义,只有结合字段 B 的值(如 B = 0 表示 ALU 操作,B = 1 表示存储器操作),才能确定 001 究竟代表加法还是写内存。

如下图所示: 微指令的编码方式

微指令的格式:

  1. 水平型微指令(三种编码方式都行): 从编码方式上看,直接编码、字符直接编码、字符间接编码都属于水平型微指令,每一位(或每一字段)直接对应一个微指令。
操作控制 顺序控制
$A_1\quad A_2\quad \dots\quad A_{n-1}\quad A_n$ 判断测试字段  后继地址字段
控制做什么 判断     下一条微指令
  1. 垂直型微指令(一个互斥段的字段直接编码方式): 在微指令中设置 微操作码字段,通过译码产生控制信号,一条垂直型微指令通常显示定义 一个 微操作。
μOP
微操作码
Rd
目的地址
Rs
源地址
  1. 混合型微指令

如下图所示: 微指令的格式 通过两道例题来分别熟悉 微指令的编码方式 和 下一条微指令形成的方式的考察方式: 两道例题

5.4.2.5 微程序控制器的设计

微程序控制器的设计步骤总览如下: 其实和硬布线控制器差不多还更加简单。 微程序控制器的设计 记得微程序控制器在每个微指令之间会有 特有操作!用取指周期示例如下: 特有操作 微程序设计分类 如下:

  1. 静态微程序设计和动态微程序设计:
    • 静态 微程序无需改变,采用 ROM
    • 动态 通过 改变微指令 和 微程序 改变机器指令,有利于仿真,采用 EPROM(电可擦除)
  2. 毫微程序设计基本概念(了解即可)
    • 微程序设计 用 微程序解释机器指令
    • 毫微程序设计 用 毫微程序解释微程序

5.4.3 硬布线和微程序的比较

硬布线和微程序的比较

5.5 指令流水线

在指令执行方案那一小节介绍过三种执行方案,前面介绍的单周期处理器采用串行的方式执行命令,而这个小节介绍的就是流水线这个方案。思维导图如下图所示: 思维导图

5.5.1 指令流水线的很多概念

提升处理器并行性的主要途径有两类:

  1. 时间上的并行:将一个任务分解成多个子阶段,各阶段由专用功能部件依次处理,并允许多个任务在不同阶段推进,即 流水线技术。
  2. 空间上的并行:在一个处理器内配置多个相同的功能部件,使其并行工作,称为 超量处理器。

典型的 五段流水线 将指令执行划分为以下阶段(前面的周期划分是逻辑上的划分,这里是硬件上的划分,是如何把一条指令拆成更小步骤,让多条指令同时执行):

  • 取指(IF):从指令存储器或缓存中读取指令。
  • 译码 / 读寄存器(ID):对指令进行译码,并从寄存器堆中读取操作数。
  • 执行 / 计算地址(EX):执行算术逻辑运算或计算有效地址。
  • 访存(MEM):访问主存储器,完成数据的读或写操作。
  • 写回(WB):将执行结果写回寄存器堆。

而 流水线的表示方法 通常使用下面两张图进行表示: 流水线的表示方法


性能指标: 指令流水线的性能指标主要有三个:吞吐率、加速比 和 效率,如下图所示: 注意:下面这些情况都是在理想情况下讨论(完美衔接)。 性能指标


流水线的设计原则:

  1. 流水段的数量以最复杂指令所需的功能段数为准。
例如:
指令 A 需要 4 个功能段
指令 B 需要 5 个功能段
指令 C 需要 3 个功能段

那么流水线应划分为:

5 个流水段

因为较短的指令也要通过这 5 个流水段,只不过某些流水段对它来说是空操作/不执行实际功能。
  1. 每个流水段的段长以最耗时的操作为准。
例如:

流水段	实际操作时间
S1	1s
S2	2s
S3	1.5s
S4	1s

那么:

流水段长度 t = 2s

为什么?

因为流水线必须按照统一的时钟节拍运行。
最慢的流水段需要 2s,其他流水段即使只需要 1s,也要占用这一个 2s 的流水周期。

计算总时间 可以这么看: 第一个任务执行完要 k t,执行完第一个任务后后面 n - 1 个任务每隔 t 执行完一个。因此 T = (k + n - 1)t

这个方法要牢记,计算总时间及其容易出错,比如最后一个阶段规定 2s ,但实际是 1 s:

| 流水段 | 实际操作时间 |
| --- | -----: |
| S1  |     1s |
| S2  |     2s |
| S3  |     1s |
| S4  |     1s |

虽然 S4 实际只需要 1s,但是流水线的统一段长已经由 S2 决定:

t = 2s

所以不能认为最后一个任务进入 S4 后只需要 1s,然后直接用实际时间去算。

指令流水线的分类: 如下图所示: 指令流水线的分类


指令流水线对指令集的要求: 为便于高效实现指令流水线,指令集应具备以下特征:

  1. 指令长度统一:简化取指与译码逻辑,避免因变长指令导致取指周期不确定。
  2. 指令格式规整:确保源操作数寄存器字段位置固定,支持在译码前预取操作数。
  3. 采用 LOAD/STORE 架构:仅允许加载(LOAD)和存储(STORE)指令访问主存,其他指令仅操作寄存器,有利于流水线段功能划分与调度。
  4. 数据与指令按边界对齐存放:确保单次访存即可获取完整操作数,避免跨周期访问,保障流水线段的原子性与时序规整性。

5.5.2 指令流水线冒险

前面说的指令分为了五个阶段,具体如下图所示: 具体五个阶段 为什么叫做指令流水线冒险,因为流水线是脆弱的,在运行过程中随时可能被阻塞,因此叫做“冒险”。

考研里面考察冒险,一定是经典五段流水线,首先需要了解流水线每段及相关指令需要做什么,如图所示: 而 导致流水线阻塞的原因及对应的解决方法 如下所示:

5.5.2.1 结构冒险(结构冲突)

资源冲突,类似操作系统中的互斥。 结构相关 解决方案:

  1. 遵循功能部件使用原则: 确保每个功能部件在每条指令中至多使用一次,且总在固定阶段使用(如寄存器写回操作统一安排在 WB 段),可避免部分结构冲突。
  2. 增加硬件资源: 例如,将寄存器堆的读口与写口分离,支持在一个周期的前半拍写、后半拍读;或将指令存储器与数据存储器分离。现代处理器的 L1 Cache 通常采用 指令 Cache 与数据 Cache 分离 的设计,从根本上消除了取指与数据访存之间的资源竞争。

5.5.2.2 数据冒险(数据冲突)

数据冲突,类似操作系统中的同步。 数据相关 如何判断是否可能存在数据冒险:

  1. 快速判断:判断一条指令 A 是否会引起数据冒险,看它 后面三条指令是否将 A 指令的输出结果作为输入。若是,则会引起数据冒险。注意若是看到指令 A 后续不足三条指令,不要忘记转移指令后面还有指令。
  2. 较全面的判断:画图。

需要注意:题目问的是可能引起数据冒险的指令,还是引起阻塞的指令。

解决方案:

  1. 延迟执行相关指令(重点): 将数据相关的指令及其后续指令都暂停若干时钟周期,直至前一条指令的结果可被安全读取。可分为软件插入 空操作(nop)指令和硬件自动插入气泡(阻塞) 两种方法。 引起数据冒险的指令 A 在 WB 阶段才写回数据,故需要将 后续指令的 ID 阶段(读数据是 ID 阶段!!)移到指令 A 在 WB 阶段之后。如图所示: 延迟执行相关指令

  2. 采用转发(旁路)技术: 设置相关转发通路,使后续指令无须等待前一条指令将计算结果写回寄存器堆,而是将前一条指令产生的结果直接转发至后续指令 EX 阶段的 ALU 输入端。

    能产生数据的指令通常在 EX 阶段产生数据( Load 指令例外),可将数据存在 EX / MEM 流水段寄存器。 当产生数据冲突的指令,进入 EX 段之后,观察所需数据是否已经产生。后续指令的 EX 段若在产生数据冒险的指令 A 的 EX 段之后,就能够被成功处理,

指令 1 2 3 4 5 6
add IF ID EX MEM WB
add IF ID EX MEM WB
  1. load-use 处理: load 指令在 MEM 阶段 结束时才能从存储器中读出数据,并将数据存入 MEM / WB 流水段寄存器。

    而紧随其后的指令如果需要使用该数据,其操作数通常要在 EX 阶段送入 ALU。此时,load 指令在该指令进入 EX 阶段时尚未产生数据,因此仅依靠数据旁路技术无法及时提供所需数据。

    因此,需要让后续指令的 EX 阶段延迟 1 个时钟周期,才能通过数据旁路技术解决冒险问题。通常可通过 插入一条 NOP 指令 实现。

指令 1 2 3 4 5 6
lw IF ID EX MEM WB
add IF ID nop EX MEM

5.5.2.3 控制冒险(控制冲突)

转移指令执行过程中,如果确定发生转移,PC 就会被修改为转移目标地址;但在确定转移结果之前,流水线可能已经根据原来的 PC 取出了后续指令。

如果最终发生转移,那么这些已经取出的指令就是错误指令,需要被清除,从而造成流水线停顿。 控制相关 如何判断是否可能存在控制冒险: 只要有转移指令就存在控制冒险,如:jmp、call、ret 等。

解决方案:

  1. 延迟分支处理:对于由分支指令引起的冲突,可由软件在分支指令后插入若干 nop 指令,或由硬件自动阻塞(插入气泡)。
指令 1 2 3 4 5 6 7 8 9 10 11
add IF ID EX MEM WB
bne IF ID EX MEM WB
add nop nop nop IF ID EX MEM WB
add IF ID EX MEM WB

注意: 转移指令在 MEM 阶段完成后,就完成了 PC 的修改。故需要把下一个指令的 IF 阶段放到转移指令的 MEM 阶段之后。 后续的指令也是同样需要后移的别忘了。

  1. 分支预测技术:尽早生成转移目标地址并预测转移方向,以减少流水线清空。静态预测采用简单规则,总是预测转移发生或不发生;动态预测根据程序运行时的转移历史动态调整预测策略,准确率更高。若预测错误,则需清空已进入流水线的错误路径指令,并从正确目标地址重新取指;若分支延迟周期数为 3,此时将损失 3 个时钟周期。

注意: Cache 缺失、中断和异常也会引起流水线阻塞(异常和中断广义上也属于控制冒险)。

5.5.3 多发技术(高级流水线技术)

有两种策略能够提升指令级的并行度:

  1. 多发射技术:通过配置多个内部功能部件,使流水线在每个时钟周期能够处理多条指令,处理器一次能够发射多条指令进入流水线执行。
  2. 超流水线技术:通过增加流水线级数,使更多的指令在流水线中重叠执行。

具体有以下三种,如图所示: 高级流水线技术

5.5.4 五段式指令流水线

前面已经提过五段式指令流水线,本节是对各指令在五段式指令流水线更具体的分析。 考研中常考的指令有五种(指令系统-指令的基本格式小节,有具体的分类):

  1. 运算类指令
  2. LOAD 指令
  3. STORE 指令
  4. 条件转移指令
  5. 无条件转移指令

分别如下图所示: 运算类指令 LOAD 指令 STORE 指令 条件转移指令 无条件转移指令 通过一个例题来理解要学习这些指令在流水线中的具体过程干什么: 例题

5.6 多处理器的基本概念

本节考研只考选择题

5.6.1 计算机体系结构分类

根据指令流和数据流的数量,计算机体系结构 可以分为四类:

  1. SISD(Single Instruction, Single Data):截止当前,前面学的所有都是这个结构。常规的单处理器属于 SISD。
  2. SIMD(Single Instruction, Multiple Data)
  3. MISD(Multiple Instruction, Single Data)
  4. MIMD(Multiple Instruction, Multiple Data): 常规的多处理器属于 MIMD。

一张思维导图总体说明: 思维导图 对于 SIMD 可能有些不清晰,用一张不太严谨的图形象化一下: SIMD

5.6.2 一些特别的处理器

有些不那么特别符合标准规范的处理器:

  1. 向量处理机: 其实就是 SIMD 的一种延伸,专门用于向量的运算(处理的对象是向量),比如矩阵: 向量处理机
  2. 共享存储多处理器系统: 共享单一物理地址存储空间的多处理器系统被称为共享存储多处理器系统。只是多处理器系统命名角度不同而已! GPT 说可以是单节点多核,也可以是多节点。 共享存储多处理器系统
  3. 多核处理器: 也是 MIMD 中的多处理器系统,只是命名角度的不同。 一个 CPU 芯片中包含多个处理器,即多个核(core),因此通常也称为片级多处理器(Chip-Level MultiProcessing, CMP)。意思是:一块芯片上集成了多个处理器 所有核共享一个 LLC(Last-Level Cache),并共享主存储器

5.6.3 硬件多线程

首先需要了解什么是硬件支不支持多线程,如下图所示: 硬件支不支持多线程 而关于硬件多线程的分类用一张图就能说明,不用深究: 硬件多线程的分类

总是在探索未知