查看原文
其他

ARM、MIPS、RISC-V三种指令集本质上有何区别?

IP与SoC设计 2022-04-29

@ 昌维


他们指令集的设计在性能优劣上还真有一定差别,例如 MIPS 为了优化分支预测失败导致的流水线惩罚,引入了分支延迟槽特性。


RISC-V 为了优化 CPU 前端(取指令和解码阶段),把指令集严格划分为了多个指令长度定长的版本,包括 RV16 压缩版,RV32-I 标准版,RV64 64bit版本等,从根源上解决了指令不定长导致的复杂设计和未对齐导致遇到下一个未对齐指令前,每个指令都需要额外的取指时间。另外如果你仔细观察会发现 RV32 的指令集里面操作数的位置几乎全部是固定在某个 bit 范围,这是为了能够在取指令后的第一时间把 寄存器索引 和 立即数 解码出来并且读取后传递给后端,而无需等待先解码出 opcode 操作码和 funct 功能码,然后再走 opcode 定位到操作数的这段组合逻辑,这是从指令及设计的根源上优化了时序,所以从理论上来说 RISC-V 属于用空间换时间的方式优化性能。当然由于现在半导体工艺提升,ROM 密度提升,成本降低,所以用空间换时间在现代技术上是合理的。


上图是 RV32I 的指令集表,可以看出无论是哪种 type ,它们的寄存器索引(rs1,rs2,rd)都是在固定的编码位置,立即数也是如此,因此解码 opcode 和解码 operand 可以同时进行。


讲完了操作数的优化,再来讲讲操作码(opcode)的优化。不知道各位在大学本科学数字电路的时候是否有接触过一种叫做“gray-code”的编码方式,中文名称叫格雷码,指的是把连续的数列(例如0,1,2...n)编码到一个每次只翻转一个 bit 的数码序列。格雷码的诞生是为了尽可能减小每次数位递增时,总共被翻转的 bit 数量。减少翻转数量的好处是降低功耗,降低干扰,优化信号完整度(只需要翻转一个 bit,意味着不需要等待多个 bit 全部翻转成功就能够满足信号完整条件),其实在指令集的 opcode 设计中也有同样的学问。例如 C 语言中经常会写 fori 循环,也就是遇到把某 2 个数字赋值成 0 以及次数后开始执行循环体,并且每次循环完成后都判断是否达到循环条件,因此一定会有一系列的指令通常是连续排列的,在opcode 设计的时候尽可能把这一系列的指令设计成类似于 gray-code 的方式,减少这一系列指令在执行时的寄存器翻转数量以优化功耗。所以你会看到无论是什么指令集,他们的 opcode 通常并不是 1,2,3 这种常规顺序编码,而是一些比较奇怪的数字,这应该是指令集的设计师根据一系列程序指令做统计后精心挑选的特殊编码。


ARM 平台我用的比较少,对它了解不是很多。


X86 平台的优劣那就有很多了。最明显的就是 X86 的寄存器全部都是专用寄存器,而非 RISC 指令集中的通用寄存器,因此执行很多操作前必须先把一些操作数 MOV 到专用寄存器才能开始操作。


当然我上面所说的都是 CPU 前端设计,前端设计本质上就是译码器的设计,再怎么优化也非常有限(比如把 CISC 译码成多个 uop 码丢入指令队列),实际上后端(ALU ,乱序执行指令重排,分支预测,缓存调度)才是优化空间很大的地方。


指令集还有一个能够决定性能的地方就是扩展性问题。


转自:https://www.zhihu.com/people/changwei1006



@ 歪睿老哥


都是risc,没有什么本质的区别。risc的众多后代,基因90%都一样。


逻辑运算都是与或非。


算数运算都是加减乘。


左移右移,要不要循环或者算数?


没事比比大小,比完跳转下一个执行,或者不管了直接跳。


读取存入,都是load,store.


甚至他们都定义了16或32个通用寄存器。


什么?你有特殊控制寄存器啊,我也定义一个,比你的还多。


你有特殊指令可以加速?我也有。我还能push和pop.


你支持位运算?这也是高科技,你真是想瞎了心了。


有的只是商业模式的区别。


举个例子,和英语,法语,德语的区别差不多。


只不过要发表文章,大家选择英语较多。


转自:https://www.zhihu.com/people/verilog_buddy



@ XIVN1987


有一个比较大的差异:ARM和MIPS指令都是固定长度的,RISC-V指令是变长的



ARM A64指令集固定32位,这通常被认为是优点,因为简化了解码,容易提升性能


但是随着ARM往A64里面塞入越来越多的指令,恐怕固定长度的缺点也在逐渐显现


比如ARM为了发力AI计算,加入了SVE指令集扩展,,SVE也是ARMv9的主要提升点,,在SVE指令中已经能感觉到一些指令长度的限制了,比如:


指令中需要编码Px寄存器,因此目的寄存器和第一源寄存器必须是同一个,这限制了灵活性


SVE ADD指令中立即数宽度只有8位,如果向量元素是16位,那向量加立即数就要拆成两条指令完成

如果ARM不想再增加一套指令集的话(现在的Cortex-A处理器需要同时支持A32、T32、A64三套指令集),A64支持变长指令恐怕在所难免


转自:https://www.zhihu.com/people/mrxian-86


本文内容仅代表作者观点,不代表平台观点。

如有任何异议,欢迎联系我们。


往期精彩回顾




2021年的第一场雪!英特尔2020年Q4财报解读



GPU基本处理流程


博文速递:Power Analysis


Chiplet与异构集成技术研究


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存