4

そこで、私の教科書 (Computer Organization and Design) を引用して、質問をします。

if-then-else を条件分岐にコンパイルする

次のコード セグメントでは、f、g、j、i、および j は変数です。f から j までの 5 つの変数が $s0 から $s4 までの 5 つのレジスターに対応する場合、この C の if ステートメントのコンパイル済み MIPS コードは何ですか?

もし (i == j) f = g + h; そうでなければ f = g - h;

図 2.9 は、MIPS コードが何をすべきかのフローチャートです。最初の式は等しいかどうかを比較するため、レジスタが等しい場合は分岐が必要なように思われます (beq)。一般に、if の後続の then 部分 (ラベル Else は以下で定義されています) を実行するコードを分岐する反対の条件をテストすると、コードはより効率的になります。 (bne):

bne $s3, $s4, Else # i ≠ j の場合は Else へ

しばらく検索しましたが、bne が beq よりも効率的である理由がわかりませんでした。(ただし、bne ステートメントのすぐ下に条件成立時に実行されるステートメントがあるため、コードが理解しやすくなるため、bne が推奨される場合があることがわかりました。)

したがって、一般的にはより効率的でない場合でも、この特定の演習ではより効率的である可能性があります. 考えてみたところ、ジャンプ命令には時間がかかるので、必要なジャンプの量を最小限に抑えたいと考えました。つまり、条件が成立すると予想される場合は bne を使用し、条件が成立しないと予想される場合は beq を使用する必要があります。

$s3 が $s4 に等しいかどうかをテストすると、これらのレジスタの内容に関する情報がまったくない場合、それらが等しい可能性が高いと仮定するのは合理的ではありません。それどころか、それらが等しくない可能性が高いため、bne の代わりに beq を使用する必要があります。

つまり、要約すると、教科書には bne が beq よりも効率的であると書かれています。それが一般的なのか、この例だけなのかは明確ではありませんが、どちらの場合も理由はわかりません。

4

2 に答える 2

1

効率は、bne と beq のマシン コードを直接比較したものではありません。このテキストでは、最も一般的なコード パスを短くするようにコーディングすることで、全体的なパフォーマンスを最適化する方法について説明しています。

値が等しくない可能性が高いと仮定すると、bne を使用するときに 1 つの命令のみを処理する必要があります。beq を使用する場合は、失敗時に追加のジャンプを実行する必要があります。

最短のパスは、比較をドロップして失敗し、ジャンプしないことです。

http://www.cs.gmu.edu/~setia/cs365-S02/class3.pdfから:

ブランチのまれなケース

ベク $18、$19、L1

  • その他の取り扱い

  • jmp

と取り換える

bne $18、$19、L2

  • サクセスハンドリング

  • 終わり

L2:

一般的なケースを高速化 - ほとんどの分岐で 1 つの命令

あなたの質問を読み直して、核心はこの仮定だと思います:

「$s3 が $s4 に等しいかどうかをテストする場合、これらのレジスタの内容に関する情報がまったくない場合、それらが等しい可能性が高いと仮定するのは合理的ではありません。逆に、それらが等しい可能性が高くなります。等しくないため、bne の代わりに beq を使用する必要があります。」

これは混乱のようです。レジスターが等しいか等しくないか、どちらの可能性が高いかを判断するための証拠または理由を見つける必要があります。

この場合、if-then-else を調べています。私は、if-test がパスすることを期待していると断言します。これは、twalberg によって説明された心理学です。レジスターには、プログラマーが予期しているデータ (前の操作の結果) が含まれているため、ランダムな値が含まれている可能性はほとんどありません。

于 2012-12-31T17:39:39.350 に答える
0

これのもう 1 つの理由は、単純な分岐予測では通常、前方分岐は行われず、後方分岐が行われると想定しているためです。この仮定により、単純なループのパフォーマンスが向上します。

于 2013-01-01T23:40:44.123 に答える