x86 で INC を使用するよりも ADD 1 の方が高速であると主張するさまざまな最適化ガイドを読みました。これは本当ですか?
2 に答える
一部のマイクロアーキテクチャでは、一部の命令ストリームを使用INC
すると、「部分フラグ更新ストール」が発生します (フラグの一部を更新しながら他のフラグを保持するため)。 ADD
すべてのフラグの値を設定するため、そのような停止のリスクはありません。
ADD
は常に よりも高速であるとは限りませんがINC
、ほとんどの場合少なくとも同程度の速度であり (特定の古いマイクロ アーキテクチャにはいくつかのコーナー ケースがありますが、それらは非常にまれです)、場合によっては大幅に高速です。
詳細については、Intel の最適化リファレンス マニュアルまたはAgner Fog のマイクロアーキテクチャ ノートを参照してください。
それは明確な答えではありませんが。次の 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 年に質問したときは、場合によっては好ましかったのですが、ADD
2016 年には常にINC
.