アニメ「火ノ丸相撲」ティザーPV
アニメ『火ノ丸相撲』
格闘技の中で相撲が一番強いのでは、と思えてきます。倒れない足腰、カッコいいですねえ。
今回もアセンブラです。
gccの最適化オプションはたくさんあります。
最適化オプション -fcaller-saves -fcse-follow-jumps -fcse-skip-blocks -fdelayed-branch -felide-constructors -fexpensive-optimizations -ffast-math -ffloat-store -fforce-addr -fforce-mem -finline-functions -fkeep-inline-functions -fmemoize-lookups -fno-default-inline -fno-defer-pop -fno-function-cse -fno-inline -fno-peephole -fomit-frame-pointer -frerun-cse-after-loop -fschedule-insns -fschedule-insns2 -fstrength-reduce -fthread-jumps -funroll-all-loops -funroll-loops -O -O2 -O3 -O0 -Os
今回は、-O、-O1、-O2でコンパイルした時の、アセンブラコードを比較してみます。
-O、-O1の説明を読むと、
最適化オプション これらのオプションは様々な種類の最適化処理を制御します。 -O -O1 最適化を行います。最適化コンパイルは幾分長めの処理時間と、大きな 関数に対 する非常に多くのメモリを必要とします。 `-O' が指定されなかった場合は、コンパイラの目標はコンパイルのコ ストを 低減することや、目的の結果を得るためのデバッグを可能とす ることに置かれ ます。それぞれの文は独立しています。つまり、ブ レークポイントでプログラムを 停止させることによって、任意の変数 に新し い値を代入したり、プログラムカウンタを他の文へと変更する ことを可能とし、 そのソースコードにプログラマが望む正しい結果を 得ることを可能にします。
-Oと-O1は同じ意味のようです。
確認してみましょう。今回もこのソースです。
takk@deb9:~/tmp$ cat -n t.c 1 int main() 2 { 3 int a=10; 4 int b; 5 if(a == 10) 6 b = 100; 7 else 8 b = 200; 9 } takk@deb9:~/tmp$
-Oオプション指定時と、-O1指定時の出力アセンブラを比較します。
takk@deb9:~/tmp$ gcc -o t-O.s -S -O t.c takk@deb9:~/tmp$ gcc -o t-O1.s -S -O1 t.c takk@deb9:~/tmp$ diff t-O.s t-O1.s takk@deb9:~/tmp$
差分なしです。manの通り-Oと-O1は同じオプションってことですね。
次は-O2オプション。
-O2 さらに最適化を行います。サポートされている最適化手段のうち、 空 間と速度のトレードオフを含まないものはほとんどの全て使用されま す。 例えばループのアンローリングや関数のインライン化は行われま せん。 -O と比較して、このオプションはコンパイル時間と生成コード の性能の双方を増加 させます。
-O1よりも、さらに最適化をするオプションのようです。
-O1と生成アセンブラを比較してみます。
takk@deb9:~/tmp$ gcc -o t-O2.s -O2 -S t.c takk@deb9:~/tmp$ diff t-O.s t-O2.s 2c2,3 < .text --- > .section .text.startup,"ax",@progbits > .p2align 4,,15 8c9 < movl $0, %eax --- > xorl %eax, %eax takk@deb9:~/tmp$
-O/-O1では、eaxレジスタへ0を入れるときに、mov命令でeaxレジスタに0格納していますが、
-O2では、eaxレジスタをxor(排他的論理和)しています。同値をxorすると0になります。レジスタのみ使用する命令は、値が必要な命令よりも、効率的なのでしょう。xorを利用した初期化で最適化しているんですね。
コメント