コンパイラの最適化オプション

今日はコンパイルの最適化オプションが単純なループと整数演算をどのくらい高速化できるかを見てみます。

サンプルプログラムをCで書きました。1からコマンド引数に渡した値まで順番に足し合わせるtest.cです。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  long long unsigned int i=0, j=0, a=atoll(argv[1]);

  while (i<a)
    j += ++i;

  printf("%llu\n", j);
  return 0;
}

 
環境は Ubuntu 12.04 の gcc version 4.6.3 を使います。

$ gcc -v
...
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

 
まずは、普通にコンパイルして実行します。

$ gcc test.c
$ time ./a.out 9876543210
11879564747017720423

real	0m21.469s
user	0m21.469s
sys	0m0.000s

 
1から9876543210まで足し合わせるのに21秒かかりました。さて、最適化オプションを試してみましょう。ちなみに -O2 で有効になっているオプションを見るにはこんな感じでコマンドを打ちます。

$ gcc -c -Q -O2 --help=optimizers | grep enabled
  -falign-functions           		[enabled]
  -falign-jumps               		[enabled]
  -falign-labels              		[enabled]
  -falign-loops               		[enabled]
  -fasynchronous-unwind-tables 		[enabled]
  -fbranch-count-reg          		[enabled]
  -fcaller-saves              		[enabled]
  -fcombine-stack-adjustments 		[enabled]
...

 
うーん。なんとなく何をしてくれるかわかるのもあれば、よくわからないのもあります。ちゃんと知りたいときはmanを読めばいいんじゃないかな。とりあえず実行速度がどうなるのか知りたいだけなので -O2 を指定して実行してみましょう。

$ gcc test.c -O2
$ time ./a.out 9876543210
11879564747017720423

real	0m2.755s
user	0m2.748s
sys	0m0.004s

 
おぉ、速くなった、速くなった。どんな理屈で速くなってるかは謎ですが、ちゃんと9876543210サイクルの計算をしてる気もします。詳しく調べてみると面白そう。せっかくだから Mac OS X Mavericks でもやってみましょう。

$ gcc test.c -O
$ time ./a.out 9876543210
11879564747017720423

real	0m0.005s
user	0m0.001s
sys	0m0.002s

 
なにこれ速すぎ。 Mavericks の xcode に入ってるコンパイラは、「これって等差数列の和を計算してるんだから、ループなんて必要ないじゃん」てことを解析してるっぽい。このコンパイラのバージョンはを見てみると、

$ gcc -v
...
Apple LLVM version 5.0 (clang-500.2.79) ...

 
これ gcc やない、LLVM clang や。どうやら Mac OS X Mavericks の gcc コマンドの中身は LLVM clang みたいです。 LLVM かしこい。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*