在 MIPS 汇编中清除寄存器(=0)的最快方法是什么?
一些例子:
xor $t0, $t0, $t0
and $t0, $t0, $0
move $t0, $0
li $t0, 0
add $t0, $0, $0
哪个效率最高?
在 MIPS 汇编中清除寄存器(=0)的最快方法是什么?
一些例子:
xor $t0, $t0, $t0
and $t0, $t0, $0
move $t0, $0
li $t0, 0
add $t0, $0, $0
哪个效率最高?
在许多 MIPS 实现中,这些操作都将编译为相同的指令,因为通常 'mov $a, $b' 是以下的成语or $a, $b, $0
和li $r, x
简写ori $r, $0, x
:
move $t0, $0
li $t0, 0
这些都将发生在同一管道上,在架构上是等效的:
xor $t0, $t0, $t0
and $t0, $t0, $0
在我使用过的每个 RISC 实现中,add 与 xor/and/nor/etc 位于同一管道上。
基本上,这对于特定芯片的实现都是特定的,但它们都应该是单时钟。如果芯片出现故障,li
或者and x, $0, $0
可能是最快的,因为它们最大限度地减少了对其他寄存器的错误依赖。
我似乎记得 $0 是专门为这种情况创建的,所以我希望这move $t0 $0
应该是清除寄存器的推荐方法。但是我已经快 10 年没有做过 MIPS 了……
鉴于所有这些指令都需要一个流水线周期,它们之间应该没有太大区别。
如果有的话,我希望xor $t0, $t0, $t0
它最适合速度,因为它不使用任何其他寄存器,因此可以让它们自由用于其他值,并可能减少寄存器文件争用。
xor 方法在某些处理器上也被视为特定的习惯用法,这允许它使用更少的资源(例如,不需要执行 XOR ALU 操作。
在 MIPS 架构的大多数实现中,所有这些都应该提供相同的性能。然而,人们可以设想一个超标量系统,它可以同时执行多个指令,只要它们使用不同的内部单元。我没有像这样工作的 MIPS 系统的实际示例,但这就是它在 PowerPC 系统上发生的方式。操作码将xor $t0, $t0, $t0
在“整数计算”单元上执行(因为它是 a xor
),而move $t0, $0
不会使用该单元;从概念上讲,后者可以与另一个执行整数计算的操作码并行执行。
简而言之,如果您发现一个系统,您列出的所有方法都不是同样有效,那么我希望该move $t0, $0
方法是最有效的。
这可能取决于同时流水线中还有哪些其他指令:上次使用寄存器的时间、下次使用的时间以及当前正在使用的内部单元。
我不熟悉任何特定 MIPS 处理器的流水线结构,但您的编译器应该是并且我希望它选择给定代码序列中最快的那个。
您可以简单地使用 $zero 寄存器作为参考,并将其值(0 或 0b00000000)写入您要清除的寄存器中。
如果您正在使用浮点数或双精度数,您可以简单地将 .data 中的浮点数和/或双精度变量声明为 0.0 并将其写入您想要随时清除的寄存器中。
例子:
.data
PI: .float 3.14
clear: .float 0.0
.text
main:
lwc1 $f0, PI
lwc1 $f0, clear
li $v0, 10
syscall