2.1 CISC 与 RISC:两条生产哲学


2.1 CISC 与 RISC:两条生产哲学

本节摘要:承接第 1 章的历史脉络,本节把 CISC 与 RISC 之争从"谁更快"的口水战里捞出来,还原为两个工程问题:复杂度放在编码里还是解码里,代码密度重要还是解码速度重要。读完你应当能独立判断一份指令集的流派立场,并理解为什么 2020 年代的 RISC-V 反而重新引入了变长编码。

两条生产哲学的分岔点

把 CISC 与 RISC 的争论想象成车间里的管理之争。一种思路认为:工单写得越满越好,一张单子写清全部工序,机床照单全收——这是 CISC。另一种思路认为:工单必须格式统一、一行一事,机床不用动脑,效率来自高速流转——这是 RISC。两边都有道理,分歧的根源是各自算的账不同。

CISC 的账本诞生于内存昂贵的 1970 年代:指令越长越强,程序越短,内存越省;解码电路复杂点没关系,反正芯片上的晶体管也不多,逻辑控制总比海量重复电路便宜。RISC 的账本诞生于 1980 年代晶体管开始富裕的节点:定长指令让解码电路极简且可流水化,省下的控制复杂度换成大寄存器堆和更深的流水线;代码密度差一点,但内存已经便宜到可以不在乎。看清这两本账,你就明白流派之争的实质:同样的语义总量,放进编码(CISC)还是放进解码(RISC),总有一头受益、一头买单。

用字节账本比较两家

空谈不如算账。同样实现"把内存里一个 32 位数加 1 后写回",看两家的典型产物:

; x86(CISC):一条指令完成 读-加-写 FF 00 ; inc dword ptr [eax] —— 2 字节 ; 典型 RISC(以 RV32I 为例,不含压缩扩展):三条指令 0007A503 ; lw a0, 0(a5) —— 4 字节,读内存 00150513 ; addi a0, a0, 1 —— 4 字节,加一 00A7A023 ; sw a0, 0(a5) —— 4 字节,写回 ; 合计 12 字节,3 条指令

CISC 一条 2 字节指令干完了全部三件事——内存到内存的直接操作让它在这种场景下代码密度占优。RISC 拆成读、加、写三条,字节数多出数倍,但每条指令的解码电路几乎一样:定长、格式齐整、字段位置固定,硬件可以像流水作业一样一个周期切一批。账到这里还没完:RISC-V 社区很快发现"每条 4 字节"在嵌入式场景太奢侈,于是推出了压缩扩展 C,把最常用的指令配了 2 字节的短编码——最 RISC 的架构,主动长出了变长编码。同理,ARM 在小内存设备时代推出 Thumb 混合编码。流派边界的松动,恰好证明两边各拿走了对方账本里最值钱的那页。

反过来,x86 也在吸收 RISC 的立场:现代 x86 核心内部把复杂指令拆成微操作再流水执行(1.4 节提过),等于把"解码复杂"的代价一次性翻译掉,之后照跑 RISC 式流水线。今天两位对手在硬件上的真实差距,早已小于它们在编码表上的观感差距。

三张表看懂立场差异

维度 CISC 立场 RISC 立场
指令长度 变长,短指令可短至一字节 定长为主,扩展后才引入短编码
访存能力 多数指令可直接访存 只有加载与存储指令访存
寄存器数量 较少(x86-64 整数 16 个) 较多(32 个起步,编译器友好)
解码电路 复杂,微操作翻译常见 简单规整,可高频流水
代码密度 天然较高 基础集较低,靠压缩扩展补齐

⚠️ 一个流传极广的误读要专门拆掉:"RISC 指令少所以程序快"。执行时间 = 指令数 × 每条周期数 × 周期时长,三者互相牵制。RISC 常常指令数更多,靠周期短取胜;CISC 指令少,但每条拆解更贵。比性能请拿具体负载实测,流派标签本身推不出结论。

判定流派的实操方法

给你一份陌生的 ISA 手册,三步定位流派。第一步翻指令长度:所有指令同一长度,RISC 血统大概率纯正;长度从 1 字节到 15 字节不等,那是 CISC 基因。第二步翻访存规则:若只有加载和存储两类指令能碰内存,Register-Only 立场无疑;若算术指令也能直接吃内存操作数,CISC 无疑。第三步看扩展机制:看它如何加新指令——是预留了编码空间慢慢加(x86 的前缀、RISC-V 的 custom 空间),还是推倒重来。三步走完,这份 ISA 的编码哲学基本现形,第 8 章展厅里我们就用这三步给 x86、ARM、RISC-V 画像。

常见疑问

问:为什么不能干脆设计一个"既定长又高密度"的完美格式?答案是这套尝试真的存在过,也真的失败了。定长与高密度的矛盾在信息论层面就拧着:定长要求每条指令有统一的字段骨架,高密度要求高频指令占用更少的位——两者同时成立,只能靠"多档定长"折中,这正是 RISC-V 的 C 扩展与 ARM 的 Thumb 走的路。但多档定长立刻带来新的复杂度:解码器要先判断当前指令属于哪一档(RISC-V 用低位与高位的组合模式判定 16 位或 32 位),对齐假设也随之松动。可见格式设计没有免费午餐,只有把复杂度搬到哪一层的区别。

问:RISC 的"访存只靠加载与存储"会不会拖慢内存密集型程序?直觉上"多一次往返"很吃亏,实测却未必:Load/Store 架构的加载与存储指令可以被处理器彼此独立地调度、乱序执行、重叠发射,而 CISC 的读改写复合指令在乱序核心里要拆成微操作(5.1 节),反而失去了在汇编层直接表达依赖的机会。内存密集场景的真正瓶颈在缓存与预取(第 6 章),不在指令条数。这也是"流派之争退位于实现之争"的一个具体注脚。

问:新指令集还有机会吗?x86 与 ARM 的存量看起来不可撼动。回答这个问题的正确框架是把"通用计算存量市场"与"增量负载市场"分开:存量市场的迁移成本是天文数字,增量市场(AI 加速、嵌入式定制、异构端侧)的软件栈本来就薄。RISC-V 与各家定制 ISA 的全部机会都在后者——8.3 节会把这层商业逻辑展开。

本节要点回顾

  • 流派之争的实质是复杂度放哪:CISC 把智能放编码,RISC 把智能放解码,总账近似、侧重不同。
  • 代码密度与解码简单性互为代价inc dword ptr [eax] 与三条 RV32I 指令的对照是这对矛盾的标本。
  • 边界在松动:RISC-V 的 C 扩展、ARM 的 Thumb 引入变长,x86 内部微操作翻译引入 RISC 化——现实 ISA 都是混血。
  • "RISC 恒快"是误读:指令数、每条周期数、周期时长三者互相牵制,性能要实测。
  • 三步判定法:看指令长度、看访存规则、看扩展机制。

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U