RISC & CISC
现代处理器的设计可以大致归入两个范畴:RISC(精简指令集)与 CISC(复杂指令集)。这并不是一个非此即彼的划分,而是一种在指令集设计哲学上的取向差异。理解它们之间的区别,有助于更深入理解CPU为何这样设计,某些优化为何必须存在,以及为何一些系统架构会对特定任务表现得更好。
起点简述
1970年代末到1980年代初,CISC 是主流方向。x86、Motorola 68000 等代表架构拥有几十甚至上百条指令,部分指令能够完成复杂的内存访问与数据变换操作。RISC 设计则是在1980年代由伯克利和IBM等提出,强调更少的指令、更固定的格式、更高的一致性,期望通过简化控制逻辑来提升指令执行效率。
核心差异
1. 指令集复杂度
-
CISC 处理器提供高度复杂的指令,如
REP MOVSB
可以一次性完成大段内存复制,甚至包括内存间的乘加操作(Load-Operate-Store)。 -
RISC 处理器提供的是原子化的操作,如单独的
LOAD
、ADD
、STORE
,每条指令完成非常明确的基本操作,长度通常固定,解码器更简单。
2. 寻址模式
-
CISC 提供多种寻址模式,如基址加变址、带偏移的间接寻址,甚至多级指针操作。
-
RISC 一般限制寻址方式,强调载入-操作-存储的模式,数据必须先从内存加载到寄存器,才能进行运算。
这种差异直接影响译码器复杂度与微架构的实现:CISC需要更复杂的微指令控制单元,RISC则便于流水线设计。
3. 指令执行周期
-
CISC 指令长度不一,执行时间也不定。部分操作可能需要多周期完成。
-
RISC 强调单周期执行,每条指令长度一致,便于实现五级或以上的流水线。
4. 微码 vs 硬件解码
-
CISC 架构通常通过微码(microcode)将复杂指令翻译成内部的简单操作。例如Intel的x86处理器内部将
MOVS
等指令分解成多个微操作(uOps)。 -
RISC 则直接用硬件电路实现指令,无需微码中转,从而降低了指令延迟和硬件复杂度。
5. 寄存器数量
-
RISC 架构(如 MIPS、ARM)通常有大量通用寄存器(32 个以上),减少对内存的依赖,提升运算效率。
-
CISC 架构(如传统 x86)寄存器较少,依赖栈帧与内存操作频繁,直到后期的x86-64才大幅增加寄存器数。
对性能与实现的影响
CISC 虽然指令功能强大,但它的复杂解码和多周期执行使得硬件优化变得困难。而 RISC 简单统一的结构使得流水线更深、更稳定,现代 CPU 超标量执行、多发射、乱序执行等高级优化大多基于 RISC 式内部设计。
事实上,现代 x86 处理器虽然前端仍支持CISC指令,但其内部微架构早已转为RISC风格:指令在进入执行单元前会被拆分成微操作(micro-ops),这些微操作再进入乱序执行引擎,这是一种典型的“CISC外壳 + RISC核心”结构。
指令范式对比:LODSB LOAD + INCREMENT
我们拿 x86 中的 LODSB
指令来举例。它是一个复合型的字符串操作指令,含义是:“从 DS:SI 指向的地址读取一个字节到 AL 寄存器,并自动将 SI 增加或减少(取决于方向标志位 DF)”。
在 CISC 中:
LODSB
单条指令,执行两个动作:内存读取 + 寄存器自增,并带隐式操作数(SI、AL、DS)。
在 RISC 中:
RISC 无法用单指令表达该操作,需拆解为:
LOAD R1, 0(R2) ; R2 = SI, R1 = AL
ADDI R2, R2, 1 ; SI++
虽然执行上需要两条指令,但好处是:
-
所有操作都是显式的,便于预测、调试与分析
-
可优化寄存器分配与指令调度
-
指令长度统一,便于流水线与乱序调度
RISC 架构通常配合寄存器重命名与指令调度器,能在多个执行单元间高效并行这类操作。
流水线实现对比
CISC 中的挑战
CISC 的可变长度指令、复杂寻址模式,使得:
-
解码单元必须有更多硬件状态机,甚至使用微码解释
-
指令长度不一,难以提前预测 fetch 窗口边界
-
难以做到真正意义的“每周期一条指令”发射
虽然 Intel 等厂商通过前端微操作解码(μop cache + μop fusion)缓解了问题,但硬件代价极高。
RISC 中的典型五级流水线(以 MIPS 为例):
-
IF(Instruction Fetch):取指
-
ID(Instruction Decode):译码并读取寄存器
-
EX(Execute):执行 ALU 运算或计算地址
-
MEM(Memory Access):访问内存(若有 LOAD/STORE)
-
WB(Write Back):写回寄存器
RISC 指令长度固定(通常为 32 位),解码逻辑简单,易于做深度流水线,甚至超级流水线(Superpipeline)和多发射(Superscalar)。
此外,RISC 便于实现流水线旁路(Forwarding)、静态调度(如 delay slot)等经典优化策略,减少数据相关引起的停顿。
CPI(Cycles Per Instruction)
理论模型:
-
RISC 平均 CPI 接近 1
-
每条指令执行一个小动作
-
配合流水线并行,理想状态每周期完成一条指令
-
-
CISC CPI 通常高于 1
-
单指令执行多步骤,微码层执行多个周期
-
解码、寻址、内存访问时间不确定
-
但需注意:RISC CPI 低不代表 RISC 更快,因为最终性能取决于:
-
程序需执行多少条指令(RISC 指令数量更多)
-
各周期的时钟频率(复杂 CISC 指令限制频率)
-
是否乱序执行/多发射/缓存命中等微架构因素
实际对比:
例如,执行一个简单的内存拷贝(128 字节):
x86 CISC 版本:
REP MOVSB
-
单条指令,硬件内部完成全部循环、判断、移动操作
-
CPI 高,但指令数少
RISC 模拟版本:
loop:
LOAD R1, 0(R2) ; 从源地址加载
STORE R1, 0(R3) ; 写入目标地址
ADDI R2, R2, 1 ; 源地址++
ADDI R3, R3, 1 ; 目标地址++
ADDI R4, R4, -1 ; 计数器--
BNE R4, R0, loop ; 循环判断
-
多条简单指令,流水线利用高
-
更适合并行执行、指令级并行优化
RISC 的 CPI 接近 1,但因为指令数高,总体执行时间未必更短。好在现代微架构能通过指令重排和分支预测等方式提高其吞吐。