CPUプロファイラを使う

最後に、CPUプロファイラの使い方を紹介する。CPUプロファイラでは、各メソッドの処理がプログラム全体の処理に対してどの程度の比率を占めているのかが解析できる。プログラムのボトルネックを解消し、パフォーマンスを向上させるのに必須のツールである。

CPUプロファイラはgoogle-perftoolsの他のツールとは違いTCMallocの一部ではない。使用方法はほとんど同じで、基本的にはコンパイル時にライブラリをリンクするだけだが、そのライブラリが異なるので注意して欲しい。リンクするライブラリはlibprofiler.soである。次のように-lprofilerを指定してコンパイルする。この例はlibprofiler.soが/usr/local/lib/以下にある場合のものだ。

-lprofilerを指定してコンパイル

$ gcc -o cpusample -L/usr/local/lib/ -lprofiler cpusample.cc

またCPUプロファイラも他のツールと同様に、コンパイル時にライブラリをリンクしないで、実行時にLD_PRELOAD環境変数にlibprofiler.soを設定する方法でも使用できる。

プログラムの実行時はCPUPROFILE環境変数にプロファイリング結果を出力するファイル名を指定する。例えば以下のように実行した場合、/tmp/myprofileに結果が出力される。

CPUPROFILEにプロファイル結果の出力先を設定して実行

$ CPUPROFILE=/tmp/myprofile ./cpusample
PROFILE: interrupts/evictions/bytes = 41/0/264

出力されたファイルの内容は、ヒーププロファイラの場合と同様にpprofコマンドで見ることが可能。例えばpprofのtopコマンドを実行してみた結果は次のようになる。ヒープの解析結果と異なるのは、メモリの使用量ではなく処理の実行時間(サンプル数)が表示さる点だ。

pprofでtopコマンドを実行した例

$ pprof ./cpusample /tmp/myprofile
Welcome to pprof!  For help, type 'help'.
(pprof) top
Total: 41 samples
      37  90.2%  90.2%       37  90.2% 0x281676f7
       4   9.8% 100.0%        4   9.8% 0x280f75cb
       0   0.0% 100.0%        4   9.8% 0x280f7203
       0   0.0% 100.0%       41 100.0% main
       0   0.0% 100.0%       15  36.6% FuncB
       0   0.0% 100.0%       41 100.0% _start
       0   0.0% 100.0%        3   7.3% FuncA
       0   0.0% 100.0%       41 100.0% _init

gvコマンドでグラフ表示した結果は次のような感じになる。実行時間が長いものほど大きなノードとして表示されるため、ボトルネックになっている可能性のある部分が一目でわかる。

CPUプロファイリングの結果をグラフ表示した例

このように、google-perftoolsを利用すればプログラムをメモリ使用量と実行速度の双方から解析し、パフォーマンスの向上につなげることができる。プログラムによってはTCMallocを使うようにするだけでも高速化が見込める上、日常で利用しているアプリケーションの高速化も実現できるかもしれない。google-perftoolsの開発チームでは、今後はNUMA(Non-Uniform Memory Access)のサポートやマルチスレッド・マルチプロセッサ環境におけるパフォーマンスの改善作業に取り組んでいくとのことだ。