2003-07-20T15:13+09:00 matsu
プログラムのパフォーマンスを効率的にあげるには,多く呼び出される関数や一番重い処理をする関数をチューニングする必要がある.ここではgccのプロファイルという機能を用いて呼び出し回数や実行時間を調べるための方法を書く.
gcc -pg
例
gcc -pg
方法はズバリ-pgでgccしてプログラムを実行するとファイルgmon.outが出力される.そしてgprofを実行するとプログラム中の各関数の実行時間や呼び出し回数等が表示される.
例
/* profile-gcc.c */
#include <stdio.h>
int hoge();
int fuga();
int foo();
int main(){
int i=0;
int j=0;
int k=0;
for(i=0;i<10;i++){
hoge();
for(j=0;j<20;j++){
fuga();
for(k=0;k<30;k++){
foo();
}
}
}
return 0;
}
int hoge(){
int i=0;
for(i=0;i<50;i++){
fuga();
}
return 0;
}
int fuga(){
int i=0;
for(i=0;i<50;i++){
foo();
}
return 0;
}
int foo(){
static int i=0;
i++;
fprintf(stdout,"%d\n",i);
return 0;
}
これを
gcc -pg profile-gcc.c
./a.out
gprof --brief
とすると
Flat profile:
Each sample counts as 0.01 seconds.
no time accumulated
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
0.00 0.00 0.00 41000 0.00 0.00 foo
0.00 0.00 0.00 700 0.00 0.00 fuga
0.00 0.00 0.00 10 0.00 0.00 hoge
Call graph
granularity: each sample hit covers 4 byte(s) no time propagated
index % time self children called name
0.00 0.00 6000/41000 main [15]
0.00 0.00 35000/41000 fuga [2]
[1] 0.0 0.00 0.00 41000 foo [1]
-----------------------------------------------
0.00 0.00 200/700 main [15]
0.00 0.00 500/700 hoge [3]
[2] 0.0 0.00 0.00 700 fuga [2]
0.00 0.00 35000/41000 foo [1]
-----------------------------------------------
0.00 0.00 10/10 main [15]
[3] 0.0 0.00 0.00 10 hoge [3]
0.00 0.00 500/700 fuga [2]
-----------------------------------------------
とでる.後半のCall graphの説明は--briefを付けなければ表示される.それによると,
fooは41000回呼ばれて,そのうち6000回はmainに呼ばれ,35000回はfugaに呼ばれた.
fugaは700回呼ばれて,そのうち200回はmainに呼ばれ500回はhogeに呼ばれた.そしてfugaは700回呼ばれた内で35000回fooを呼んだ.
hogeは10回よばれ,10回ともmainに呼ばれた.そして500回fugaを呼んだ.
ということになる.左部の[1]が付いているのは「fooについてだよ」,[2]は「fugaについてだよ」,[3]は「hoge」についてだよ,という意味である.fooについての部分ではfooの上にあるのがfooを呼んだ関数,fooの下にあるのがfooが呼んだ関数である.