指令周期
指令周期
复习定位
一条指令从内存中取出到执行完成所经历的时间称为指令周期。不同的指令(加法/跳转/访存)所需的指令周期数不同——但都遵循取指→译码→执行的基本模式。理解指令周期对于理解CPU的执行时间(程序=多少条指令×每个指令的周期数)和CPU性能至关重要。
指令的取指阶段
- 程序计数器(PC)的当前值→存储器地址寄存器MAR→地址总线→存储器。
- 存储器根据地址找到对应的指令字→数据总线→存储器数据寄存器MDR。
- MDR→指令寄存器IR。
- PC自增(加上当前指令的长度——x86变长指令需要预译码器确定指令长度)。
取指阶段对所有指令都是相同的——与指令类型无关。
指令译码阶段
控制单元译码器分析IR中的操作码——生成对应的控制信号——确定需要取哪些操作数——输出到ALU控制线和各选通信号。
指令执行阶段
不同指令的执行阶段差异很大——分为几个类型:
算术逻辑指令(如ADD R1, R2, R3)——1个周期
- 从寄存器文件读取R2和R3→送到ALU输入多路选择器。
- ALU根据控制信号做加法→结果进入ALU的输出端。
- 结果写入R1(在写回阶段后生效)。
访存指令(如LOAD R1, [addr])——可能需要2-3个周期
- 计算地址(基址+偏移)→地址寄存器→地址总线→存储器。
- 等待存储器读取数据→数据总线→MDR→ALU或目标寄存器。
- 如果使用Cache(且命中)——只需1个额外周期;如果不命中——需要从主存读入。
条件跳转指令(如JZ label)——1个周期+可能的流水线刷新
- 计算目标地址(PC+偏移)。
- 检查条件码标志位(由前序指令设置)。
- 如条件满足——PC←目标地址;否则PC←PC+1(继续下一条)。
- 在流水线中——如果分支预测错误——需要清空后面已取指的指令(分支惩罚)。
微操作序列
每个指令周期被分成更小的步——称为微操作(micro-operation)——由控制单元在一个时钟周期内完成。例如ADD R1,R2的取指阶段可分解为:
T1: MAR ← PC (将PC值送入内存地址寄存器)
T2: MDR ← Memory[MAR] (从内存读取指令)
PC ← PC + 1 (PC自增)
T3: IR ← MDR (指令写入指令寄存器)不同指令在译码和执行阶段的微操作序列各不相同——但取指阶段的几乎所有微操作对所有指令都是相同的。复杂指令(如x86的ADD EAX, [EBX*4+ECX])需要更多的执行微操作来计算地址和访存。
指令周期的可变性
简单寄存器指令——取指→译码→执行(1周期)→写回(1周期)=最短周期数。LOAD指令——取指→译码→计算地址→内存读→写回=更多周期。STORE指令——取指→译码→计算地址→内存写——不写回寄存器。
CISC指令的周期数差异巨大——例如x86的DIV指令可能需要10-40个周期——而RISC指令大多数在单周期或双周期内完成——所以RISC-CISC的比较不只是指令数目的差异。处理器流水线的每个阶段对应一个指令周期的不同步骤。
复习检查
取指阶段对所有指令都是相同的——为什么?取指阶段只负责从PC指向的内存中读取指令——不关心它是什么类型。
条件跳转指令的执行阶段——为什么需要检查条件码——因为决定是否跳转依赖于前一条指令的结果——前一条指令通过设置标志位(ZF/CF/OF)影响跳——条件跳转指令本身不产生条件,而是依赖于条件码状态。
LOAD指令比ADD指令为什么需要更多的执行周期——LOAD需要计算地址、访问内存(读操作)——而从L1/末级Cache到寄存器一整套阶段必须完成——而ADD操作的所有操作数已在寄存器中——计算较快。
微操作序列中——MAR←PC和PC←PC+1可以在同一周期吗——取决于CPU的硬件设计——如果ALU可以同时做加法——可以在同一周期完成多个独立微操作。
指令周期与取指周期的区别——指令周期包括取指+译码+执行+写回(可能包含多个时钟周期)——取指周期只是指令周期的一个子阶段(从内存读取指令到IR的固定阶段)。