ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

408计组:指令系统与中央处理器核心考点与计算套路

408计组:指令系统与中央处理器核心考点与计算套路 1. 指令系统这章的骨架三条主线串起所有考点我第一次系统刷 408 计组的指令系统时最大的感受是这一章的知识点看起来都很短小但一做题就到处漏风。指令格式、寻址方式、扩展操作码、CISC 与 RISC单拎出来每一条都能背下来可一旦放进选择题里尤其是那种给出指令字长和地址码位数、让你算某一级最多能编多少条指令的题目立刻就卡住。到了中央处理器这一章寄存器的位数、数据通路的微操作序列、微指令的编码方式、流水线的三类冒险又是一堆看起来互不相干的名词堆在一起。后来我把这两章重新过了一遍发现它们根本不是散装知识点而是一条完整的线索指令系统规定了机器能听懂哪些话中央处理器负责把这些话翻译成电路级的动作。把这条线抓住零碎的知识点会自动归位。如果你正在准备考研 408或者正在做计组的课程设计这两章的重要性怎么强调都不过分。指令系统是后续所有内容的语法基础中央处理器则是整门课唯一把硬件怎么跑起来讲透的地方。它不像存储器那章可以靠公式硬算也不像 I/O 那章可以靠背接口名称过关它要求你真的理解数据在总线上是怎么流动的。下面这份笔记是我自己整理并反复验证过的版本包含原理推导、计算套路和我踩过的坑适合零基础先建立框架也适合二轮复习时用来查漏。1.1 指令格式每一位都在花预算一条指令就是一段二进制串它的格式设计本质上是一个预算分配问题。指令字长是总预算操作码要占一部分地址码要占一部分两边是互相挤压的关系。操作码字段决定这台机器最多能有多少种操作地址码字段决定一条指令能直接指出几个操作数。按地址码个数分常见的有三地址、二地址、一地址和零地址指令。三地址指令形如ADD R1, R2, R3一次运算三个地址全给足表达力最强但最费空间二地址指令ADD R1, R2通常把结果写回第一个地址隐含了目的操作数一地址指令往往隐含一个累加器比如ADD X表示ACC ACC X零地址指令则完全依赖栈顶元素常见于堆栈型机器比如ADD直接弹出两个栈顶数相加再压回。这里有一个容易被忽略的细节地址码的位数取决于寻址空间的大小。如果主存按字节编址、容量是 4MB那么地址位数至少是 22 位因为 2^22 4M。反过来如果题目告诉你地址码是 12 位那它直接寻址的范围就是 4KB 个存储单元而不是 4KB 字节——这两者在按字编址和按字节编址下结论完全不同。我自己做题时就因为混淆过存储单元数和字节数栽过跟头后来养成一个习惯看到地址码位数先在心里默念一句这是能寻多少个单元不是多少字节。指令字长还分定长和变长两种。定长指令字长便于译码和流水线设计几乎所有的 RISC 机器都走这条路变长指令字长可以灵活压缩高频指令节省存储空间x86 就是典型代表。408 里有一类常考的判断题会问变长指令字长的机器不可能采用流水线这就是明显的错误选项——x86 内部会把变长指令译码成定长的微操作再进入流水线执行只是前端多了一层译码开销。1.2 扩展操作码本质是一套前缀不冲突的编码扩展操作码是这一章最容易出计算题的地方也是最容易被解法套路带偏的地方。很多资料会告诉你每一级留一个编码作为扩展标志这句话本身没错但它只是操作方法不是原理。原理其实只有一条码字必须是前缀无关的任何一个短操作码都不能是另一个长操作码的前缀否则译码时会产生歧义。这个思路和哈夫曼编码里的前缀码一模一样。拿一个经典配置来说指令字长 16 位每个地址码 4 位。三地址指令的操作码占 4 位可以编出 16 个码字编号 0000 到 1111。如果我们要在这台机器上再编二地址指令那二地址指令的操作码就变成 8 位而它的高 4 位必须落在三地址没有用掉的码字上。假设三地址指令一共设计了 15 条那么 0000 到 1110 已经被占用只剩 1111 空闲。把 1111 当作二地址操作码的高 4 位就能得到 1111 0000 到 1111 1111 这 16 个二地址码字。如果二地址也只设计 15 条剩下的 1111 1111 继续作为一地址操作码的高 8 位又能展开 16 个一地址码字。再往下一地址用掉 15 条后剩 1111 1111 1111作为零地址操作码的高 12 位最后得到 16 条零地址指令。这个推导过程给出的结论是每一级可用的码字数等于上一级剩余码字数乘以 2 的地址码位数次方。在上面的例子里就是 1 × 16 16、1 × 16 16、1 × 16 16。如果把三地址改成只设计 14 条那么剩下 1110 和 1111 两个前缀二地址的码字空间立刻变成 2 × 16 32 个。这就是为什么题目里只要一动某一级的指令条数后面所有级别的上限都会跟着变。我用过的计算模板是这样的级别操作码位数可用码字来源码字总数三地址4全码空间16二地址8三地址剩余码字 × 16剩余数 × 16一地址12二地址剩余码字 × 16剩余数 × 16零地址16一地址剩余码字 × 16剩余数 × 16注意所谓预留一个扩展标志只是当你还需要往下扩展时才需要做的事。如果某一级已经不需要再展开它剩下的码字可以全部给这一级用不必浪费一个。1.3 指令类型与指令字长、边界对齐指令按功能大致分成几类数据传送类MOV、LOAD、STORE、PUSH、POP、算术逻辑类ADD、SUB、AND、OR、比较、移位类算术移位、逻辑移位、循环移位、转移类无条件转移、条件转移、调用与返回、串操作类、输入输出类。408 不会考你背指令助记符但会考哪一类指令必须访存。这个问题的答案很明确只有取数指令和存数指令会访问主存这是 RISC 的核心特征之一而 CISC 里很多运算指令本身就允许操作数直接来自主存比如ADD R1, (R2)这种形式。边界对齐是另一个高频细节。如果机器按字节编址但要求指令字长 32 位对齐那么所有指令的起始地址必须是 4 的倍数也就是说地址的最低两位恒为 00。这样一来转移指令里的目标地址字段可以省掉最低两位用更少的位表示更大的范围。考试里常见问法是某机按字节编址指令字长 32 位且按边界对齐存放转移指令的偏移量字段为 16 位以指令为单位则转移范围是多少。这时候要记得把 2 的 16 次方乘以 4 字节得到 256KB 的跳转范围而不是想当然地按字节算。2. 寻址方式把有效地址怎么来和要访存几次拆开看寻址方式这块内容看起来零散其实只有两个核心问题操作数的有效地址 EA 是怎么算出来的以及为了拿到操作数需要访问几次主存。把这两个维度当成一个二维表格去记比按顺序背十条定义要牢得多也更抗遗忘。2.1 十种寻址方式的 EA 推导与访存次数先明确一个前提下面说的访存次数指的是取操作数本身需要访问主存的次数不含取指令的那一次。取指令永远是 1 次除非采用间接寻址取指令这种极端设计408 不涉及。寻址方式有效地址 EA取操作数访存次数典型用途立即寻址无地址码就是操作数0常数赋值直接寻址形式地址 A1访问固定变量间接寻址M[A]2指针、跳转表寄存器寻址寄存器内容0临时变量运算寄存器间接寻址M[R]1指针操作相对寻址PC A1程序内跳转基址寻址BR A1程序重定位变址寻址IX A1数组遍历堆栈寻址栈顶指针0 或 1过程调用传参隐含寻址默认操作数0累加器、栈顶这张表我建议自己动手默写三遍。尤其是立即寻址和寄存器寻址它们的访存次数都是 0因为在取指阶段操作数已经跟着指令一起进到 CPU 里了这是很多人下意识答错 1 次的地方。2.2 相对寻址那个最容易错的基准地址相对寻址的计算是这一章最高频的计算题也是最容易掉坑的地方。规则只有一句目标地址 下一条指令的地址 偏移量偏移量是有符号补码数。关键在于下一条指令的地址也就是已经加过指令长度之后的 PC 值而不是当前指令的地址。举个具体例子。某机按字节编址指令长 2 字节当前转移指令存放在地址 2000H 处偏移量字段为 8 位补码值为 08H。那么取指完成后 PC 已经自增为 2002H目标地址 2002H 0008H 200AH而不是 2000H 8 2008H。如果偏移量是负数比如 F6H8 位补码表示 −10那么目标地址就是 2002H − 000AH 1FF8H。这里还有一个隐藏考点偏移量的范围由位数决定。8 位补码能表示 −128 到 127如果以字节为单位就是向前 128 字节、向后 127 字节的跳转范围但如果题目说偏移量以指令为单位范围就要乘以指令长度。我自己的记法是画一条时间线指令在 2000H 开始取指结束后 PC 指向 2002H跳转从 2002H 开始算。只要这个画面在脑子里题就不会算错。2.3 变址与基址形式相同用途完全不同基址寻址和变址寻址的表达式长得一模一样都是寄存器内容 形式地址但两者的设计目的完全不同这是选择题的高频干扰点。基址寻址里基址寄存器 BR 的内容由操作系统或系统程序给定在程序运行过程中不变形式地址 A 作为偏移量由用户程序填写。它的用途是程序重定位——同一段程序加载到内存不同位置时只要改 BR 的值所有地址自动跟着平移。变址寻址反过来变址寄存器 IX 的内容由用户程序改变形式地址 A 通常作为数组首地址固定不变。循环遍历数组时每执行一次就IX IX 1用同一条指令访问不同元素。用一句话区分基址寻址是基址不动、偏移变变址寻址是基址数组首地址不动、寄存器变。严格说这两个不动的对象不同前者固定的是 BR后者固定的是 A。我在模拟题里见过把两者描述互换的选项只背定义不看用途就很容易选错。3. CISC 与 RISC这一章所有为什么的答案很多同学复习到这里会犯一个错误把 CISC 和 RISC 当成两个需要死记硬背的知识点背完特性表就往下走。实际上这两条路线的分歧是整章内容的解释框架。为什么 RISC 偏爱硬布线控制器为什么 RISC 几乎都能做流水线为什么 CISC 需要微程序控制器这些问题的答案全都指向同一个源头指令系统的复杂度决定了控制器的实现方式。3.1 两种路线的取舍清单CISC复杂指令集的设计哲学是让硬件去迁就软件指令数量多、功能强、长度可变、寻址方式丰富一条指令能干很多事编译器写起来省心。代价是译码电路复杂控制器很难用硬布线实现只能走微程序路线而微程序执行速度慢又制约了流水线的实现。RISC精简指令集反过来是让软件去迁就硬件。指令数量少、长度固定、寻址方式只有几种所有运算指令的操作数都必须在寄存器里只有 load 和 store 能访问主存。指令简单带来的好处是控制器可以用硬布线直接搭建速度极快而且定长指令让流水线的每一段都能对齐实现起来自然顺手。对比项CISCRISC指令数量多通常几百条少几十到一百多条指令长度变长格式多定长格式少寻址方式丰富十几种少几种访存指令多数指令可访存仅 load/store 访存通用寄存器数量少多控制器实现以微程序为主以硬布线为主流水线实现难度高低优化责任方主要靠硬件主要靠编译优化典型代表x86 系列ARM、MIPS、RISC-V3.2 高频干扰项与判断技巧这一节的题目基本都在考辨识我把见过的错误选项归成几类。第一类是方向颠倒比如RISC 的指令数量比 CISC 多CISC 更容易实现流水线。第二类是绝对化表述比如RISC 一定不采用微程序控制器——注意是一定出了问题RISC 的设计初衷是硬布线但早期有些 RISC 机器也用过微程序实现只是效率不占优。第三类是把寄存器和访存混在一起比如RISC 允许算术运算指令直接访问内存这一条恰恰是 RISC 明确禁止的。我自己总结的判断口诀是看变量不看形容词。只要选项里出现一定完全绝不这类词先打个问号只要选项把指令长度访存权限控制器实现这三件事的描述互换基本可以判定为错。另外补充一个现实中的常识现代的 x86 处理器虽然对外还是 CISC 接口但内部会把复杂的变长指令翻译成类似 RISC 的微操作再执行这说明两条路线在实际工程里是互相借鉴的而不是非此即彼。4. CPU 的物理构成寄存器和数据通路中央处理器的组成可以拆成两半运算器负责算控制器负责指挥。运算器里有 ALU、累加器、移位器、通用寄存器组和程序状态字控制器里则是指令寄存器、程序计数器、指令译码器、微操作信号发生器和各种时序电路。这部分内容在 408 里最常见的考法是给出一串微操作问需要几个时钟周期或者问某个寄存器的位数是多少。4.1 六个必背寄存器的位数与职责寄存器部分的坑集中在位数上因为同一个寄存器在不同配置下的答案不同必须结合题目条件推。PC程序计数器存放即将执行指令的地址位数取决于指令地址空间。如果程序空间是 4GB 按字节编址PC 需要 32 位。PC 有自增功能可以在取指阶段自动加 1 或加指令长度。IR指令寄存器存放当前正在执行的指令位数等于指令字长与主存容量无关这是最容易搞混的一条。MAR存储器地址寄存器位数等于地址线根数也就是log2(存储单元总数)。注意是按单元数取对数不是按字节数。MDR存储器数据寄存器位数等于存储字长也等于数据线宽度。如果存储字长 32 位MDR 就是 32 位。PSW程序状态字存放各种标志位常见的包括进位标志 CF、零标志 ZF、符号标志 SF、溢出标志 OF。其中 CF 和 OF 的区别是经典考点进位标志是最高位产生的进位溢出标志是有符号数运算结果超出表示范围。无符号加法溢出看 CF有符号溢出看 OF两者没有必然联系。通用寄存器组数量多、速度快用于暂存操作数和中间结果RISC 里通常有 32 个甚至更多。有一个细节值得单独提题目经常问取指周期完成后IR 和 MDR 的内容分别是什么。答案是 IR 拿到的是整条指令MDR 拿到的是从主存读出的那个存储字。如果存储字长恰好等于指令字长两者内容相同如果存储字长小于指令字长比如存储字 16 位、指令 32 位那么取一条指令需要访问两次主存MDR 里的内容只是其中一半。4.2 单总线数据通路上的微操作序列数据通路是指令执行时数据经过的路径和部件。单总线结构的核心限制是同一时刻总线上只能有一个部件输出数据所以两个寄存器之间的传送必须分时进行。以取指周期为例在单总线结构下需要这样几步(PC) → MAR // PC 的内容送到地址寄存器 M(MAR) → MDR // 从主存读出指令送数据寄存器 (MDR) → IR // 数据寄存器内容送指令寄存器 (PC) 1 → PC // PC 自增指向下一条指令这四步每一对括号之间都是一次总线占用因此在单总线结构下取指至少需要 4 个时钟周期。如果题目给的是双总线或多总线结构能并行传输的部分可以合并周期数就会减少。这就是为什么做题时一定要先看清楚总线的条数。再看一个完整的加法指令ADD (R1), R2含义是把 R1 指向的主存单元内容与 R2 相加结果写回 R2(R1) → MAR M(MAR) → MDR (MDR) → Y // 送入暂存器 Y (R2) → ALU // 另一操作数送 ALU 输入端 (Y) (R2) → Z // ALU 运算结果存暂存器 Z (Z) → R2 // 写回寄存器这条指令一共需要访问主存一次取操作数加上取指的几次整个指令周期就拉长了。而如果改成ADD R1, R2这种纯寄存器运算全程不需要访存指令周期会短很多。这也解释了 RISC 为什么坚持只有 load/store 访存——访存是流水线里最慢的一段能省则省。4.3 指令周期的四级划分与三级时序指令周期通常划分为四个阶段取指周期、间址周期、执行周期、中断周期。其中间址周期只有采用间接寻址的指令才有这是判断题的常客。中断周期只在响应中断时才进入。时序上分三级时钟周期节拍 机器周期 指令周期。时钟周期是最小的时间单位由主频决定机器周期是一组微操作的集合通常对应一次访存所需的时间指令周期则是一条指令从取出到执行完毕的全部时间。常见问法是某机主频 1GHz机器周期包含 4 个时钟周期平均每条指令需要 3 个机器周期求指令平均执行时间。算法就是 3 × 4 × 1ns 12ns注意单位换算别把 GHz 当成 ns 直接用。一个容易忽略的点CPU 主频和机器周期并不总是整数倍关系有的机器一个机器周期包含的时钟周期数是不固定的。408 里如果没有特别说明默认按固定节拍处理。5. 控制器实现硬布线与微程序的分岔口控制器这一节的内容密度最高概念也最密集。它回答的是同一个问题译码之后那些控制信号到底从哪儿来。硬布线和微程序是两条不同的答案理解它们的取舍比背下所有名词更重要。5.1 硬布线为什么快但改不动硬布线控制器的思路很直接把指令译码信号、时序信号、状态标志全部送进一堆组合逻辑电路输出就是各个部件的控制信号。因为信号走的是纯粹的门电路延迟只有几级门的传播时间所以速度快是它最大的优势RISC 机器基本都这么干。它的缺点同样明显控制逻辑全部固化在电路里一旦要增加或修改指令就得重新设计电路成本极高。另一种说法是硬布线控制器不便于扩充指令这句话是对的。另外要注意硬布线控制器虽然是组合逻辑为主但为了产生有先后顺序的控制信号仍然需要配合时序系统不能说它完全不需要时钟。从设计方法上讲硬布线控制器的设计流程是列出每条指令在每个机器周期需要执行的微操作为每个微操作分配一个控制信号然后写出每个控制信号的逻辑表达式用门电路实现。这个流程在 408 里考得不深一般只要求理解原理和对比优劣。5.2 微程序控制器的一组核心概念微程序控制器的思路是把控制信号存起来。它用一条条微指令来表示一个机器周期内要做的所有微操作若干条微指令组成一个微程序每个微程序对应一条机器指令。所有微程序存放在一个只读的高速存储器里叫控制存储器 CM它的访问速度直接决定了机器周期能有多短。这组概念里最容易混的是三兄弟微命令、微操作、微指令。微命令是控制器发出的最底层控制信号比如打开 R1 输出门微操作是由微命令引起的部件动作比如R1 的内容送到总线微指令则是一个时钟周期内发出的所有微命令的集合。它们的关系是一条微指令包含若干微命令若干微命令驱动出若干微操作。还有一对必须分清的数字机器指令条数决定微程序的个数微指令的条数决定控制存储器的容量。当题目问控制存储器至少要多少个单元就要把所有微程序包含的微指令总数算出来。特别注意取指微程序是所有指令共用的只存一份但每个指令的执行微程序里通常都要包含它计算时不要重复计入。5.3 微指令编码方式与字长计算微指令的格式分两大部分操作控制字段和顺序控制字段后者也叫下地址字段用来指明下一条微指令在 CM 中的地址。操作控制字段的编码方式有四种考试里主要考前两种直接编码水平型一个微命令对应一位某位为 1 就发出对应微命令。优点是译码快、并行能力强缺点也很直接——如果有 40 个微命令操作控制字段就有 40 位微指令字长非常长。字段直接编码把互斥的微命令不会同时发出的归到同一个字段里字段内的每个编码代表一个微命令同时每个字段必须留一个编码表示本字段不发任何微命令。这是计算题的关键。若某字段内有 n 个互斥微命令则该字段需要ceil(log2(n1))位。举个例子某个微指令的操作控制字段分为 4 个字段微命令数分别是 7、8、3、5。按字段直接编码计算字段微命令数需留空码需要位数字段一783字段二894字段三342字段四563操作控制字段共需 3 4 2 3 12 位。如果采用直接编码则需要 7 8 3 5 23 位。省下 11 位代价是增加译码电路的延迟这个权衡关系是理解两种编码方式的核心。另外两种是字段间接编码字段中的编码还需要另一个字段解释和混合编码408 考得很少知道名字和大致思路就够了。5.4 两张对比表把硬件和微程序钉死对比项硬布线控制器微程序控制器控制信号来源组合逻辑电路直接产生控制存储器中的微指令速度快慢需读 CM灵活性差修改需改电路好改微程序即可规整性差逻辑零散好规整易扩展适用场景RISC、高速机器CISC、指令复杂的机器微指令的格式也分两种水平型微指令并行能力强、微程序短但微指令字长长垂直型微指令类似机器指令、字长短但并行能力弱、微程序长。这是另一组经典的对比考点判断时抓住字长和并行性的反向关系就够了。6. 流水线重叠执行带来的性能红利与三类冒险流水线是中央处理器这一章的收尾也是计算量最大的部分。它的核心思想很朴素把一条指令的执行拆成若干段让不同指令的不同段在时间上重叠起来从而让每个时钟周期都有一条指令完成。这个思想和工厂的装配线完全一样理解了装配线性能公式就自然推得出来。6.1 三条性能公式与算例设流水线有 k 段每段耗时一个时钟周期 T连续执行 n 条指令。那么第一条指令需要 k 个周期填满流水线之后每个周期完成一条剩下 n − 1 条需要 n − 1 个周期总时间 (k n − 1) × T。在这个基础上三个性能指标就都能算了吞吐率 TP n / ((k n − 1) × T)当 n 趋于无穷时最大吞吐率为 1/T也就是每个周期完成一条指令加速比 S 串行执行时间 / 流水线执行时间 (k × n × T) / ((k n − 1) × T) k × n / (k n − 1)理想情况下趋于 k效率 E 有效面积 / 总面积 (k × n) / (k × (k n − 1)) n / (k n − 1)。拿一个具体的配置算5 段流水线每段 1 个时钟周期执行 100 条指令。总时间 (5 100 − 1) × T 104T。串行需要 500T。加速比 500/104 ≈ 4.81吞吐率 100/104T ≈ 0.96/T效率 100/104 ≈ 96.2%。可以看到段数越多理论加速比上限越高但实际受限于流水线建立和排空的开销指令条数越少效率越低。这里有个高频陷阱如果各段耗时不等流水线的时钟周期由最慢的那一段决定而不是平均值。比如某流水线五段耗时分别是 2ns、3ns、2ns、4ns、2ns那么时钟周期是 4ns其余段都要插入等待。这种情况下计算总时间必须按最慢段算不能把各段相加除以段数。6.2 三类冒险的成因拆解流水线跑起来之后会遇到三种让理想情况破产的问题结构冒险也叫资源冲突。典型场景是指令流水线在同一时刻既要取指令又要访问数据而两者用的是同一个存储器。解决办法是把指令 Cache 和数据 Cache 分开这就是哈佛结构相对冯诺依曼结构的优势所在。另一种常见冲突是寄存器堆同时被两条指令读写这个通过设置独立的读写端口就能解决。数据冒险后面指令需要用到前面指令还没算完的结果。看这段代码I1: ADD R1, R2, R3 ; R1 R2 R3 I2: SUB R4, R1, R5 ; R4 R1 - R5I2 在译码段要读 R1但 I1 的结果要到写回段才写进 R1中间差了两段。解决办法是转发旁路把 ALU 刚算出来的结果直接送到下一条指令的 ALU 输入端不走寄存器堆。上面的例子通过转发就能消除停顿。但有一种情况转发救不了就是load-use 冒险I1: LW R1, 0(R2) ; 从内存读 R1 I2: ADD R3, R1, R4 ; 立即使用 R1I1 的数据要到访存段结束才拿到而 I2 在执行段一开始就需要它时间上差了整整一段。这时候即使有转发也必须插入一个停顿周期。这是流水线部分最爱考的一个点有转发不代表零停顿load-use 至少要停一拍。控制冒险转移指令改变了 PC但流水线已经按照顺序预取了后面的指令这些预取的指令可能是错的。分支指令的目标地址要到执行段才算出来而预取发生在取指段中间隔了好几个周期。6.3 转发、停顿与分支预测的消解手段针对控制冒险处理方法有几种。最简单的叫插入气泡也叫流水线停顿把错误的指令丢弃重取代价是若干个空闲周期。好一点的做法是提前计算转移地址在译码阶段就完成比较和目标地址计算把要丢弃的指令数从三条降到一条。再先进一点的是分支预测静态预测简单粗暴地假设转移总是发生或总是不发生动态预测用两位饱和计数器记录历史行为比如一个分支连续两次跳转后才预测跳转这样在循环结构中只在最后一次预测错误。还有一种思路叫延迟槽让编译器把一条无论如何都要执行的指令填到转移指令后面这样那条指令无论分支是否成立都能正常完成白白利用了一个周期。关于动态预测补充一个容易考的判断两位饱和计数器的状态在 00 到 11 之间变化遇到跳转就加一遇到不跳转就减一只有在 10 状态再遇到不跳转才降到 01 并改变预测方向。这类细节在选择题里出现过理解状态机的走向就能答对。6.4 超标量、动态流水线与超流水线的区别流水线本身也在演进几个术语容易混类型核心特征效果基本流水线每周期取一条指令加速比趋近于段数超标量每周期取多条指令有多条并行流水线提高并行度超流水线把每段再细分提高时钟频率缩短时钟周期动态流水线允许不同指令的不同段在时间上重叠错位支持乱序执行超标量是横向加宽超流水线是纵向加细这两个概念经常被出题人拿来互换描述设置陷阱。动态流水线相比静态流水线允许非同类指令在同一时刻处于不同阶段实现更复杂但效率更高。现代高性能处理器往往是几者结合既超标量又超流水还带动态调度。7. 我复盘这一章时的顺序与踩过的坑把这两章完整过完一遍之后我总结出一条比较顺的复习路径分享给同样在啃这部分内容的人。先抓指令格式和寻址方式因为这两块是所有后续内容的基础没搞清 EA 怎么算后面做任何访存相关的题都会卡接着把 CISC 和 RISC 的对比吃透这是理解控制器和流水线设计动机的钥匙然后进入 CPU 组成和时序重点放在寄存器位数和微操作序列上最后攻控制器和流水线这两块计算量最大也最需要动手推。7.1 一条自测路径我给自己设计的自测顺序是这样的拿到任意一个指令字长和地址码位数的配置能在两分钟内推出各级指令的码字数量上限给出任意一条汇编指令能写出它在单总线数据通路上的完整微操作序列并数出需要的时钟周期数给出主频、机器周期包含的时钟数、平均机器周期数能算出指令平均执行时间给出流水线段数、每段耗时和指令条数能算出吞吐率、加速比和效率给定微命令分组能算出字段直接编码下操作控制字段的位数。这五条都能顺利过关说明这部分的知识已经成体系了而不是零散记忆。7.2 反复踩的四个坑第一个坑是相对寻址的基准地址。我至少错过三次原因都是下意识用了当前指令地址。现在我会强制自己在草稿纸上先写下PC 已自增四个字再动笔。第二个坑是MDR 和 MAR 的位数。我一度以为 MDR 位数等于数据总线宽度就一定等于存储字长实际上在有些题目里两者并不一致必须分开确认。判断口诀是MAR 看地址线MDR 看存储字长。第三个坑是微程序个数和微指令条数。一开始我总把它们混为一谈后来明确记住微程序个数由机器指令数量决定加上公共的取指微程序控制存储器容量由微指令总条数决定。第四个坑是load-use 冒险的停顿周期数。我早期错误地认为只要有转发就不需要停顿实际上 load-use 至少需要插入一个气泡周期。判断方法很简单看生产者指令的数据在哪一段产出消费者指令在哪一段需要两者的时间差如果大于转发能覆盖的范围就要停顿。最后补一个小技巧这一章的名词密度极高我用的办法是把每个核心概念都压缩成一句它解决了什么问题。比如转发解决的是结果还没写回就被需要分支预测解决的是指令地址还没算出来就要预取微程序解决的是控制逻辑改不动。当你能用一句话说出每个技术的存在理由选择题里的概念辨析基本就不会错了。这套方法我在做计组课程设计的时候也用过从指令格式设计到数据通路搭建每一处取舍背后其实都能对应到这两个章节里的某个原理。
返回列表