加载失败
这篇讨论围绕 Righto.com(一个做芯片拆解和逆向分析的博客)对 Intel 8087(Intel 为 8086 配套的浮点协处理器)内部 microcode 的拆解,重点是其中一段名为 register exchange 的微操作流程。8087 使用 80-bit 浮点格式,因此既能提供更高精度,也让实现、验证和异常处理更复杂。评论区把它放进更大的架构演化里比较:早期常用 microprogram ROM(微程序 ROM)实现复杂控制,后来 RISC(精简指令集)和 VLIW(超长指令字)则尝试用更简单的指令和更快的存储层次来替代。大家还拿 IBM System/360、Apollo Guidance Computer 和 FPS AP-120B 等例子说明,性能、成本、可维护性和与主 CPU 的并行关系,都会影响这类芯片的设计取舍。
评论主要在追问 8087 的 microcode 设计细节,特别是为什么微指令格式里没有常见的显式控制流位。有人想知道 RNI 为什么单独成指令,以及寄存器传送后的延迟为何迫使很多槽位都像 nop。讨论的核心其实是:在这种微码引擎里,控制流到底该做成自动递增、显式跳转,还是把分支信息编码进地址。
一条很有意思的线索是 Intel 当年有工程师专门处理客户浮点 bug report,核心工作几乎就是复现边界案例。评论指出,很多投诉并不是程序崩了,而是同样的 fp 运算换个顺序就得到不同答案,用户对“正确结果”的期待各不相同。这里反映出的不是单纯的性能问题,而是浮点舍入、精度损失和语义约定带来的长期支持成本。
有人把问题延伸到:既然 microcode 更容易开发、测试和修 bug,那后来为什么不直接把成熟设计改成 hardwired/discrete logic 来提速。回复的观点是,这种改造通常不值得,尤其是已经稳定之后再回头修 bug 会非常痛苦。评论还提到少数例外,比如 IBM System/360 的高端机、Apollo Guidance Computer 和 NEC V33,它们在特定场景下为了性能选择了不同的实现路线。
另一条争论是:为什么不把那 8 类简单操作直接放到正常 RAM 里执行,甚至让用户自己编写,外加一个小 cache。回应把这思路直接对应到 RISC 和 VLIW 的演化:早期机器把复杂控制塞进 ROM microprogram,是因为高速 cache 太贵,而后来才转向简单指令加更快的存储。评论还举了 FPS AP-120B(1976 年的浮点加速器)这个早期“超长指令字”式案例,但它的成本远高于 8087,而且 8087 还要和 8086 并行工作,所以让它频繁从 RAM 取微指令并不划算。
microcode(微码/微程序): 处理器内部用来实现复杂指令的一层低级控制程序,常存放在 ROM 中。
microprogram ROM(微程序 ROM): 存放微指令的只读存储器,用来驱动 CPU 或协处理器的内部控制流程。
RISC(精简指令集): 强调简单、规则、易流水化的指令设计,减少对复杂 microcode 的依赖。
VLIW(超长指令字): 一条指令中打包多个可并行操作,由编译器或前端安排并行度。