指令解码将指令中携带的信息提取出来,处理器使用这些信息控制后续流水线执行。指令集的复杂度决定了这一阶段的复杂度。CISC 相比 RISC,指令长度不固定,寻址方式更复杂。即使是 RISC 指令集,也有一些另类的指令,不能使用一般的处理方法,如一些指令的目标寄存器多于一个,会影响寄存器重命名,如有些指令可以条件执行。这些指令出现频率不高,需要在解码阶段进行转换,不需要再后续流水线增加硬件。

指令缓存

为了减少 I-Cache 缺失带来的影响,处理器可以在取值阶段取出多于可以解码的指令个数,在取值和解码阶段添加一个缓存 instruction buffer 用来保存。加入缓存后,取值阶段最终会输出两个主要的部分给这个缓存(假设每周期取 4 条指令)。

  1. 四条指令,不过未必全部有效。
  2. 有效指令的个数。当取指令的地址落在 Cache line 的最后三个字,或者指令组中存在被预测跳转的分支,会导致取指令阶段无法向指令缓存中写入四条指令。

指令缓存本质是 FIFO,它能将指令按照程序中指定的顺序存储起来,指令在解码时,仍保持原有的顺序。指令缓存的重要性体现在:

  1. 超标量处理器中,每周期取的指令个数大于每周期解码的指令个数,即使 I-Cache 缺失时,指令缓存中仍有一些余量的指令,如果 I-Cache 缺失很快解决,基本就不会引起流水线的暂停。
  2. 有些特殊指令无法在解码阶段全部处理,有时候会将一条指令拆分为两条。 由于指令缓存每周期可以写入、读出多条指令,它是个多端口 FIFO,但是实际设计会使用交叠 interleaving 的方式用单端口 FIFO 实现这个功能。