21

私は今、組み立てコースを受講しています。私たちの家の課題をチェックする人は、非常に衒学的な昔ながらの最適化フリークです。たとえば、次のような場合は 10% を控除します。

mov ax, 0

それ以外の:

xor ax,ax

たとえ一度しか使っていなくても。

私はアセンブリ プログラミングの完全な初心者ではありませんが、最適化の専門家でもありません。そのため、何かについてあなたの助けが必要です (非常にばかげた質問かもしれませんが、とにかく尋ねます): レジスタ値を 1 に設定する必要がある場合または(-1)を使用する方が良いですか:

mov ax, 1

または次のようなことをします:

xor ax,ax
inc ax

私は本当に良い成績が必要なので、できるだけ最適化しようとしています。(時間とコードサイズの両方を最適化する必要があります)

4

4 に答える 4

14

Pentiumを介した8086/8088のすべてのタイミングとサイズがあるように見える命令タイミングのリストをすばやくグーグルで検索し8086 instructions timings sizeました。

ただし、これには、特に 8088 で非常に重大なコード フェッチ メモリのボトルネックが含まれていない可能性があることに注意してください。これにより、通常、コード サイズの最適化がより適切な選択になります。詳細については、こちらを参照してください。

「8086/8088 User's Manual: Programmer's and Hardware Reference」など、同様の情報が記載された公式の Intel ドキュメントがウェブ上で見つかることは間違いありません。

特定の質問について、以下の表は、後者が優れていることを示す比較を示しています(サイクルが少なく、スペースが同じ):

指示 クロックサイクル バイト
xor axe、ax
in axax
3
3
---
6
2
1
---
3
ムーヴアックス、1 4 3

しかし、あなたはこの男についてあなたの教育機関と話したいと思うかもしれません. そのような単純なことに対する 10% のペナルティは、かなり厳しいように思えます。1 つは速く、もう 1 つは短いという2 つの可能性がある場合、どうすればよいかを尋ねる必要があります。

次に、達成しようとしていることに応じてコードを最適化するさまざまな方法があることを彼らが認めたら、あなたがしようとしているのは読みやすさと保守性を最適化することであり、真剣に気にすることはできないと伝えます.あちこちの無駄なサイクルまたはバイトについて(1) .

最適化は、コードの一部がほぼ完全な状態になった後、パフォーマンスの問題が発生した場合に一般的に行うものです。コードがまだ重要な変更の可能性にさらされている場合、ほとんどの場合、無駄な労力になります。

価値があるのは、クロックサイクルとサイズの点でsub ax,ax同等に見えるxor ax,axので、次回はそれをミックスに投入して、彼にもう少し仕事をさせることができるかもしれません.


(1)いいえ、実際にはそんなことはしませんが、たまに吐き出すのは楽しいです :-)

于 2010-05-13T13:14:41.163 に答える
3

あなたはより良いです

移動AX,1

8086 で。レジスタの内容を追跡している場合、たとえば、BX に既に 1 が含まれていることがわかっている場合は、より適切に実行できる可能性があります。

移動AX、BX

または AH が 0 であることがわかっている場合:

移動 AL,1

于 2010-06-29T20:41:47.083 に答える
2

mov [e]ax, 1どんな状況でも使います。そのエンコーディングは、よりハックなxorシーケンスよりも長くはなく、ほぼどこでも高速であると確信しています。8086 は例外であるほど奇妙であり、それは非常に遅いため、このようなマイクロ最適化が最も大きな違いを生むでしょう。しかし、それ以外の場合: 2 つの「簡単な」命令を実行すると、1 つを実行するよりも常に遅くなります。特に、データ ハザードと長いパイプラインを考慮する場合はそうです。レジスタを変更した直後の命令でレジスタを読み取ろうとしているので、CPU が結果をパイプラインのステージ N (xor実行中) からステージ N-1 (inc が実行中の場所) にバイパスできない場合を除きます。値に 1 を追加しても構いません)、ストールが発生します。

その他の考慮事項: 命令フェッチ帯域幅 (16 ビット コードの場合は意味がありません。どちらも 3 バイトです)。movフラグの変更を回避します (すべてのフラグを強制的に 0 にするよりも役立つ可能性が高くなります)。他のレジスタが保持する可能性のある値に応じて、おそらく実行できますlea ax,[bx+1](32ビットコードでも3バイト、フラグには影響しません)。他の人が言ったようsbb ax,axに、状況によっても機能する可能性があります-2バイトと短いです。

この種のマイクロ最適化に直面したときは、プロセッサのマニュアルに盲目的に頼るのではなく、実際に代替案を測定する必要があります。

PS 新しい宿題: (任意のプロセッサで)xor bx,bxよりも高速ですか?xor bx,cx

于 2010-05-13T19:31:18.030 に答える
2

あなたの状況によっては、あなたは逃げることができるかもしれません...

 sbb ax, ax

結果は、キャリー フラグが設定されていない場合は 0 になり、キャリー フラグが設定されている場合は -1 になります。

ただし、上記の例があなたの状況に当てはまらない場合は、

xor  ax, ax
inc  ax

方法。それはサイズのためにあなたの教授を満足させるはずです. ただし、プロセッサがパイプライニングを採用している場合、2 つの命令間にカップリングのような遅延が発生することが予想されます (これは間違いである可能性が非常に高いです)。このような結合が存在する場合は、命令を少し並べ替えて、間に別の命令 (ax を使用しない命令) を配置することで、速度をわずかに改善できます。

お役に立てれば。

于 2010-05-13T13:18:46.390 に答える