gcc-4.1 で プロファイルを利用した最適化を行う(その1)

コンパイラでプロファイルを利用した最適化を行うと,例えば条件分岐の頻度をサンプルすることで分岐予測の精度を高めることができ,その結果より最適化されたバイナリが生成できる.

例えば,以前のgccでは gcov コマンドと gcc の -fprofile-arcs -ftest-coverage オプションを組み合わせでプロファイルベースの最適化が行えた*1

一方,最近のgcc-4.1などでは,プロファイルベースの最適化は以下の手順で行う.

  • コンパイラオプションで -fprofile-generate を指定してバイナリを生成する
  • バイナリを数回実行し,最適化に必要な情報を収集する.
  • コンパイラオプションで -fprofile-use を指定してバイナリを生成する.

仕組みとしては,

  • -fprofile-generate を付けて作成したバイナリは,実行時にプロファイルを行い結果を,拡張子 gcno のファイルに保存する.
  • -fprofile-use を付けて作成したバイナリは, *.gcno のファイルの情報を元に最適化されたバイナリを作成する.

また,拡張子 gcno のファイルは,バイナリにリンクされた各 *.o 毎に生成される.

gcc-4.1 で プロファイルを利用した最適化を行う(その2)

実際に gcc-4.1.0 で -fprofile-generate -fprofile-use を使ってみた.使用したコードは,手元にあった自作のもの.26028ステップもあります(涙

両オプションは コンパイル時とリンク時 両方で指定する必要がある.

$ export CPPFLAGS="-fprofile-genereate"
$ export LDFLAGS="-fprofile-genereate"
$ make clean
$ make 

バイナリを数回動かして,データをサンプルする.

$ export CPPFLAGS="-fprofile-use"
$ export LDFLAGS="-fprofile-use"
$ make clean
$ make 

2回目のbuildでは,以下のようなワーニングが出たりするが,

thread_core.cpp: In function '(static initializers for thread_core.cpp)':
thread_core.cpp:409: note: file thread_core.gcda not found, execution counts estimated

とりあえずベンチマークの結果は以下のようになった.

適用前 適用後
ある処理の処理時間平均(msec) 245 229

一割ほど速くなっている??