V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xieyuheng
V2EX  ›  程序员

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

  •  
  •   xieyuheng ·
    xieyuheng · 191 天前 · 2362 次点击
    这是一个创建于 191 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

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

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

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

    isa 里规定的寄存器也不等于 cpu 物理上真的只有这么多。cpu 真实的寄存器数量很可能大于 isa 里的寄存器数量,因为 cpu 内部为了减少指令间依赖会做寄存器重命名
    CRVV
        11
    CRVV  
       191 天前
    @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
        12
    mmdsun  
       191 天前 via iPhone
    @felixlong
    编程语言更看中平台的独立性,基于栈的指令集不依赖于特定数量的寄存器,更容易在不同的硬件和操作系统上移植。Python 、JVM 、dotNET 、甚至 WebAssembly 都是基于栈。
    e3c78a97e0f8
        13
    e3c78a97e0f8  
       191 天前
    @summerLast x86 和 ARM 可都是基于寄存器的,和题主问题没关系。
    roycestevie6761
        14
    roycestevie6761  
       191 天前
    函数调用不都是寄存器不够了再入栈吗,设计一个基于栈的不是退化吗,寄存器肯定比内存访问快太多了
    DeWjjj
        15
    DeWjjj  
       191 天前
    因为 ARM 的电路更多,有的时候为了实现模拟 x86 的算法需要多次缓存数据。
    roycestevie6761
        16
    roycestevie6761  
       191 天前
    而且有一些专门做代码混淆的人基于栈式指令集搞出来的基于堆栈的虚拟机,这种机子复杂的一批,但是同时执行起来也慢的一批
    misdake
        17
    misdake  
       191 天前
    核心原因就是性能差。
    ISA 比较灵活,依赖比较小,改做 AOT 的字节码还是很合适的。
    felixlong
        18
    felixlong  
       191 天前
    @mmdsun 基于栈主要是为了节省空间和简单。和可移植多大没关系,同样是 Java ,Android VM 就是基于寄存器的。
    基于栈的 JVM 每条指令只要一个 byte 编码。基于寄存器的 Android VM 每条指令需要 2 个 byte 。X86/ARM 都是需要 4 byte 得。
    tek
        19
    tek  
       191 天前
    STACK 式的操作速度慢,是用更多的操作步骤换取实现的简单。设想在一个电视机的组装流水线上,用有两只手的机器人来完成工作需要 n 个步骤。如果换用一只手的机器人来完成同样的工作,必然需要更多的拿起,放下的步骤和更多的周转空间。但单手机器人结构更简单,造价更低
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5338 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 47ms · UTC 07:04 · PVG 15:04 · LAX 00:04 · JFK 03:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.