为什么编译器必须针对 RISC 指令集架构“更智能”

为什么编译器必须针对 RISC 指令集架构“更智能”

精简指令集架构 (RISC) 旨在减少指令数量,从而提高性能。这种方法的唯一缺点是编译器必须“更智能”。

我的讲师说“编译器必须更智能”,她到底是什么意思?为什么会这样?

答案1

RISC,老实说,代表“降低指令集复杂度”——指令的数量不一定会减少,但每个指令都更简单,包括执行该指令所需的机器周期数以及用于执行该指令的门(或微码存储器)的数量。

理论(至少部分实现)是,通过减少控制逻辑的数量,可以为寄存器和数据路径提供更多的芯片空间。因此,RISC 机器的寄存器数量通常是 CISC 机器的 2-4 倍。

这样,编译器就可以完成省略的控制逻辑的工作,包括“调度”操作(对它们进行排序),这样,您就不必连续执行两个加法,而是先执行加法,然后执行移位(并在不同的寄存器上执行),这样加法器和移位器都得到了最佳利用。而且,编译器还必须管理寄存器集,以优化寄存器的进出,最大限度地减少存储访问。此外,编译器必须知道如何最好地利用奇数指令(例如“左移一位并用文字掩码”),因为这些指令通常在某些(可能很奇怪)的场景中相对强大。

因此,好的 RISC 编译器生成的指令几乎不可能被破译。即使你很了解指令集,找出半小时前的值仍然在寄存器 12 中也是很困难的,即使没有一直发生的复杂的移位和掩码操作。

(对于那些显然不相信我知道自己在说什么的人,我第一次参与 IBM 801 的 RISC 是在 70 年代初期,当时我和 George Radin 和 Marty Hopkins 是熟人。)

答案2

由于 RISC CPU 中的指令较少,因此单个高级语句很好地转换为单个机器语言操作码的可能性较小。

RISC CPU 的同义词是“加载-存储架构”。基本上,这意味着实际工作的 RISC 指令通常仅在寄存器上工作。如果您想要处理存储在 RAM 中的值,则必须发出显式 LOAD 指令,而 x86 等 CISC CPU 则具有自动执行此操作的指令。RISC CPU 历来比 x86 拥有更多的寄存器 - 并且好的代码将很好地管理可用的寄存器以避免不必要的内存访问,这意味着编译器需要考虑到这一点。

另一件事是,RISC CPU 通常仅提供链接所需的最少“基础设施”。

例如,x86 CPU 有“堆栈”的概念,您可以在其中推送值,然后“弹出”它们(有PUSHPOP指令)。还有一条CALL指令 - 它将当前指令指针推送到堆栈上,然后跳转到目标地址 - 通常是子例程或函数。RET然后可以稍后发出一条指令来弹出保存的指令指针并从原始函数恢复。嵌套子例程很方便,您可以使用PUSHPOP轻松地为子例程放置参数。

例如,在 MIPS 上,您只有jal“跳转和链接”——它将当前指令指针放在寄存器中,然后跳转到该地址。如果您想执行堆栈或 x86CALL指令之类的操作,则必须手动执行。这需要编译器具有更多的智能。

答案3

CISC(复杂指令集计算)处理器比 RISC(精简指令集计算)处理器具有更大范围的指令。

CISC 中的乘法示例为:MUL 1:3, 4:2(将 1:3 和 2:4 相乘)。此命令将加载其寄存器中位置 1:3 的值,加载 4:2 中的值,将它们相乘并将其存储回 1:3

RISC CPU 可能必须:

  • 负载 A,1:3
  • 负载 B,4:2
  • 产品A、B
  • 商店 1:3,A

...4 个 RISC 操作到 1 个 CISC 操作。

因为 RISC 甚至需要更多的操作才能完成最简单的乘法计算——想象一下视频渲染或游戏之类的事情需要多少工作?

考虑到这一点 - 从程序员输入的代码构建软件的编译器需要“更智能”,以便他们知道如何简化 RISC 架构的复杂代码和复杂命令。

希望这是有意义的为了进一步阅读,可能值得一看: http://www.engineersgarage.com/articles/risc-and-cisc-architecture?page=5

相关内容