为什么市面上没有很流行的基于栈的指令集构架(ISA),而全是基于寄存器的?

205 天前
 xieyuheng

我只知道 Forth 语言的作者设计过一些基于栈的小众 CPU 。

https://en.wikipedia.org/wiki/Charles_H._Moore

基于栈的构建,所有参数都可以用栈来传递,感觉指令集可以更精简。

那么为什么市场上没有这样的指令集流行呢?是因为它有什么别的劣势吗?

2382 次点击
所在节点    程序员
19 条回复
billlee
205 天前
1. 手写汇编的时候,基于寄存器的指令集更直观
2. 电路里又没有栈,用栈做指令集还要增加电路来模拟栈的行为,指令集精简但电路却更复杂
felixlong
205 天前
1 , 慢。
2 ,java 的指令集就是基于 stack 的。
wniming
205 天前
借楼问一下,为啥 x86 使用 16 个通用寄存器而 arm64 使用 31 个?是不是通用寄存器越多 ipc 就会越高?
summerLast
205 天前
硬件设计导致的。
寄存器比内存更快(速度更快,离 cpu 更近,但是也小),缓存次之,内存在次之,
容量从小到大
速度从快到慢
寄存器的空间有限,因此要知道哪些是高频数据,利用好它的速度。

我们换个思路去思考这个问题,现在你有一台图灵机的原型,请问如何改进提高性能和响应速度?

据个不是那么恰当的例子:内存是个放在桌子上的记事本,寄存器直接是瞬时记忆
summerLast
205 天前
@wniming 历史原因,额,就比如 x86 是复杂指令集的代表 ARM 是精简指令集的代表,但现实是 x86 现在里面有许多指令最后执行的指令的复杂度也和 ARM 没太大区别了。
summerLast
205 天前
@wniming 理论是越高,但我们有那么多高频数据吗?,所以结果是提升有限。
UN2758
205 天前
@wniming 你可以把寄存器理解为指令周期级别延迟的缓存,cpu 的流水线长度和应用场景还有边际效用决定了民用 cpu 不值得做太多寄存器
kita
205 天前
@summerLast 我不认为对,现在 cpu 的 IPC 都是靠 Icache 在拉的。寄存器和指令没有什么关联性

@wniming x64 才有 16 个吧
iOCZ
205 天前
精简指令集参数多了才会入栈吧
agagega
205 天前
@wniming
x86 的指令操作数可以直接是内存地址,所以不需要那么多名义寄存器。arm 这类精简指令集必须要 load/store 才能从内存里读/写信息,isa 寄存器数量少了会有大量 spill/reload

isa 里规定的寄存器也不等于 cpu 物理上真的只有这么多。cpu 真实的寄存器数量很可能大于 isa 里的寄存器数量,因为 cpu 内部为了减少指令间依赖会做寄存器重命名
CRVV
205 天前
@wniming
16 个寄存器需要 4 位来编码,31 个需要 5 位,这个应该是最主要的原因。
比如 inc eax 只需要 1 个 byte ( 8 位)来编码。如果寄存器需要 5 位,就不太可能放在 1 byte 里面。( ARM 好像也没有 inc 这个指令)
所谓 CISC ,是指在一条指令里面可以同时访问内存和做运算。比如 add eax, (ecx),是 eax += *ecx ,这条指令在 x86 上面只占 2 bytes
在 RISC 上面需要先 load edx, (ecx),再做加法 add eax, edx ,RISC 上面这两条指令很可能都要 4 bytes ,一共 8 bytes 。而且 load ecx 需要多用一个寄存器 edx 来保存结果。也就是 RISC 需要更多的寄存器来做到的 CISC 一样的事情。
指令短是 CISC 的一个重要设计目标,到 RISC 的年代不在乎这个事了,所以有这个差别。

CPU 实际有多少个寄存器和指令上定义的寄存器数量无关,CPU 有一部分专门来处理这个事情
https://en.wikipedia.org/wiki/Register_renaming
mmdsun
205 天前
@felixlong
编程语言更看中平台的独立性,基于栈的指令集不依赖于特定数量的寄存器,更容易在不同的硬件和操作系统上移植。Python 、JVM 、dotNET 、甚至 WebAssembly 都是基于栈。
e3c78a97e0f8
205 天前
@summerLast x86 和 ARM 可都是基于寄存器的,和题主问题没关系。
roycestevie6761
205 天前
函数调用不都是寄存器不够了再入栈吗,设计一个基于栈的不是退化吗,寄存器肯定比内存访问快太多了
DeWjjj
205 天前
因为 ARM 的电路更多,有的时候为了实现模拟 x86 的算法需要多次缓存数据。
roycestevie6761
205 天前
而且有一些专门做代码混淆的人基于栈式指令集搞出来的基于堆栈的虚拟机,这种机子复杂的一批,但是同时执行起来也慢的一批
misdake
205 天前
核心原因就是性能差。
ISA 比较灵活,依赖比较小,改做 AOT 的字节码还是很合适的。
felixlong
205 天前
@mmdsun 基于栈主要是为了节省空间和简单。和可移植多大没关系,同样是 Java ,Android VM 就是基于寄存器的。
基于栈的 JVM 每条指令只要一个 byte 编码。基于寄存器的 Android VM 每条指令需要 2 个 byte 。X86/ARM 都是需要 4 byte 得。
tek
205 天前
STACK 式的操作速度慢,是用更多的操作步骤换取实现的简单。设想在一个电视机的组装流水线上,用有两只手的机器人来完成工作需要 n 个步骤。如果换用一只手的机器人来完成同样的工作,必然需要更多的拿起,放下的步骤和更多的周转空间。但单手机器人结构更简单,造价更低

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/983524

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX