19

x86 で INC を使用するよりも ADD 1 の方が高速であると主張するさまざまな最適化ガイドを読みました。これは本当ですか?

4

2 に答える 2

31

一部のマイクロアーキテクチャでは、一部の命令ストリームを使用INCすると、「部分フラグ更新ストール」が発生します (フラグの一部を更新しながら他のフラグを保持するため)。 ADDすべてのフラグの値を設定するため、そのような停止のリスクはありません。

ADDは常に よりも高速であるとは限りませんがINC、ほとんどの場合少なくとも同程度の速度であり (特定の古いマイクロ アーキテクチャにはいくつかのコーナー ケースがありますが、それらは非常にまれです)、場合によっては大幅に高速です。

詳細については、Intel の最適化リファレンス マニュアルまたはAgner Fog のマイクロアーキテクチャ ノートを参照してください。

于 2012-11-14T16:58:07.973 に答える
6

それは明確な答えではありませんが。次の C ファイルを作成します。

=== inc.c ===
#include <stdio.h>
int main(int argc, char *argv[])
{
    for (int n = 0; n < 1000; n++) {
        printf("%d\n", n);
    }
    return 0;
}

次に実行します。

clang -march=native -masm=intel -O3 -S -o inc.clang.s inc.c
gcc -march=native -masm=intel -O3 -S -o inc.gcc.s inc.c

生成されたアセンブリ コードに注意してください。関連する clang 出力:

mov     esi, ebx
call    printf
inc     ebx
cmp     ebx, 1000
jne     .LBB0_1

関連する gcc 出力:

mov     edi, 1
inc     ebx
call    __printf_chk
cmp     ebx, 1000
jne     .L2

これは、clang と gcc の両方の作成者が、最新のアーキテクチャINCよりも優れた選択であると考えていることを証明しています。ADD reg, 1

それはあなたの質問にとって何を意味しますか? まあ、私はあなたが読んだガイドに対する彼らの判断を信頼し、それINCは同じくらい高速でADDあり、より短いレジスタエンコーディングのために節約された1バイトが望ましいと結論付けます. コンパイラの作成者は単なる人間なので、間違っている可能性はありますが、ありそうにありません。:)

オプションを使用しない場合は-march=native、gcc がadd ebx, 1代わりに使用することが、さらにいくつかの実験で示されています。Clang otoh は、常に inc が一番好きです。私の結論としては、2012 年に質問したときは、場合によっては好ましかったのですが、ADD2016 年には常にINC.

于 2016-05-08T02:17:36.820 に答える