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を行っていません...
これらのすべての命令が 1 つのパイプライン サイクルを使用することを考えると、それらの間に大きな違いはないはずです。
もしあれば、xor $t0, $t0, $t0
他のレジスタを使用しないため、速度が最適であると予想されます。したがって、他の値のためにそれらを解放し、レジスタファイルの競合を減らす可能性があります。
xor メソッドは、一部のプロセッサでは特定のイディオムとしても扱われるため、使用するリソースがさらに少なくなります (たとえば、XOR ALU 操作を実行する必要がありません)。
MIPSアーキテクチャのほとんどの実装では、これらすべてが同じパフォーマンスを提供するはずです。ただし、個別の内部ユニットを使用している限り、複数の命令を同時に実行できるスーパースカラーシステムを想定できます。そのように機能するMIPSシステムの実際の例はありませんが、それがPowerPCシステムでどのように発生するかです。xor $t0, $t0, $t0
オペコードは「整数計算」ユニットで実行されますが(整数計算であるため)xor
、move $t0, $0
そのユニットは使用されません。概念的には、後者は整数計算を実行する別のオペコードと並行して実行できます。
簡単に言えば、リストするすべての方法が等しく効率的ではないシステムを見つけた場合、move $t0, $0
私はその方法が最も効率的であると期待します。
$zero レジスターを参照として使用し、その値 (0 または 0b00000000) をクリアしたいレジスターに書き込むだけです。
float または double を使用している場合は、float または double 変数を .data で 0.0 として宣言し、いつでもクリアしたいレジスタに書き込むことができます。
例:
.data
PI: .float 3.14
clear: .float 0.0
.text
main:
lwc1 $f0, PI
lwc1 $f0, clear
li $v0, 10
syscall
おそらく、同時にパイプライン内にある他の命令によって異なります。レジスタが最後に使用されたのはいつか、次に使用されるのはいつか、現在どの内部ユニットが使用されているかです。
私は特定の MIPS プロセッサのパイプライン構造に精通していませんが、コンパイラはそうあるべきであり、与えられたコード シーケンスで最速のものを選択することを期待しています。