コンパイル最適化
コンパイル最適化
C言語はアセンブリが速くない.C言語はコンパイラからアセンブリに翻訳しなければならないからだ.コンパイラは結局人工的で、翻訳されたアセンブリソースコードにはいつもN本の命令があり、より知能的で創造的な私たちから見れば余計だ.
C言語翻訳後のアセンブリには、次のような悪質な行為があります.
movl i, %eax
addl $1, %eax
movl %eax, i
eaxレジスタがiの値を常に保持していても、C言語はそれを操作する前に読むのが好きで、以上の3つの命令が1つのincl%eaxに濃縮されると速度が何倍も速くなります.
C言語は「このように耐えられない」にもかかわらず、高度な言語がもたらすソースの可読性と開発効率の数の向上を考慮して、私たちはそれを許しました.また、多くのコンパイラには最適化を提供するオプションがあり、最適化オプションをオンにした後、C言語で翻訳されたアセンブリコードは申し分ありません.VC,VSはDebug,Releaseコンパイルモードがあり,Releaseでコンパイルするとプログラムのサイズ,実行効率が著しく改善される.gccにも最適化オプションがあります.gcc最適化の不思議な効果を見てみましょう.
わざとゴミプログラム(math.c):
#include <stdio.h>
int main()
{
int a=1, b=2;
int c;
c = a + a*b + b;
printf("%d
", c);
return 0;
}
最適化されていない場合、アセンブリコードがどんなに悪いかを見てみましょう.
コンパイルコマンド:gcc-S math.c mainセクションのアセンブリコード:
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $1, 28(%esp) # 28(%esp) a
movl $2, 24(%esp) # 24(%esp) b
movl 24(%esp), %eax #\
addl $1, %eax #-\
imull 28(%esp), %eax #-eax=(b+1)*a
addl 24(%esp), %eax #\
movl %eax, 20(%esp) #-c=(b+1)*a+b
movl $.LC0, %eax
movl 20(%esp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
call printf
movl $0, %eax
leave
ret
アセンブリコードの規模は膨大で、翻訳レベルは規則的です.最適化オプションをオンにします.
コンパイルコマンド:gcc-O 2-S math.c
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
movl $5, 4(%esp)
movl $.LC0, (%esp)
call printf
xorl %eax, %eax
leave
ret
の規模は元の半分になり、gccはa、b、c変数が余分であることを発見し、結果5をprintfに直接印刷した--計算機はコンパイラに必要な大きなスキルである.中学生の時、計算問題を一生懸命やっていたのに、どうしてC言語を勉強しなかったのですかO(∩∩)O~