プロファイリング
アプリケーションの実行時間を短縮するようにプログラムを改良することをチューニングという.チューニングを行うためには,アプリケーションの性能を測定する必要がある.アプリケーションの性能を分析するをプロファイル・プロファイリングといい,またそのためのツールをプロファイラという.プロファイリングによりもっとも実行時間がかかっている場所を特定し,その部分を高速化すると,高いチューニング効果が得られる.
時間計測
プログラムの実行時間を簡便に計測する方法として,以下のような方法がある.ここでは,シリアルプログラムのみを考える.並列プログラムの場合は,測定しているものが経過時間か各コアが使用された時間の総和なのか,については注意が必要.
- timeコマンドを使う
- 時間計測関数をプログラムに埋め込む
- プロファイラを使う
timeコマンド
UNIX/Linux環境では時間を計測するtimeコマンドがある.timeコマンドは引数として指定したコマンドの実行時間を測定する.
time ./a.out
real ??m??s
user ??m??s
sys ??m??s
realは起動から終了までに経過した時間,userはユーザCPU時間,sysはシステムCPU時間である.プログラム自体の処理時間はuserをみればよい.なお,timeコマンドにはいくつかの種類があり,出力が異なる場合がある.
C言語の場合
ANSI標準で定められた標準ライブラリに日付や時間に関する関数がある. これを用いるにはtime.hをインクルードする.time.hでは以下のような関数や定数が定義されている.
clock_t clock(void)
- 関数clockは実行開始時からプログラムが使用したプロセッサ時間を返す.(利用できない場合は -1 を返す.)
CLOCKS_PER_SEC
-
関数
clock
の戻り値の単位を定義する.clock()/CLOCKS_PER_SEC
とすれば単位が秒に変換される. clock_t
-
関数
clock
の戻り値の型を定義する.通常long型.
プログラム例は以下のようになる.適当な処理の実行にかかる時間を計測するには,その処理の前後でclock
関数を呼び出し,その時間差から経過時間を求める.
#include <time.h>
int main() {
clock_t time_start, time_end;
time_start = clock()/CLOCKS_PER_SEC;
適当な作業
time_end = clock()/CLOCKS_PER_SEC;
printf(“elapse time in second = %d\n”,time_end-time_start);
}
Fortranの場合
Fortran95規格で標準化されたサブルーチンcpu_time
が利用できる.
subroutine cpu_time(time)
real, intent(inout) :: time
cpu_time
は引数にプロセッサ時間[秒単位]を返す.C言語の例と同様のプログラムは以下のようになる.
program time_some_code
real :: time_start, time_end
call cpu_time(time_start)
適当な処理
call cpu_time(time_end)
print *, “elapse time in second = “, time_end - time_start
end program time_some_code
Matlabの場合
関数cputime
はアプリケーションを起動してからの総CPU時間[秒]を返す.
(ただし,パフォーマンス測定には関数timeitやtic/tocの利用が推奨されている.)
t = cputime;
適当な処理
e = cputime - t
プロファイリングツール:GNU gprof
GNU binutilsに含まれる簡便なプロファイリングツールであり,Linux環境で利用可能.詳細な利用方法についてはマニュアルを参照されたい.基本的な使い方は以下のとおり:プログラムのコンパイル時にオプション-pgをつけると,プログラム実行時にプロファイリング情報がgmon.outというファイルに記録される.プロファイル情報を解析するにはgprofコマンドに実行ファイル名,プロファイル情報ファイルを引数として与えて実行すればよい.
gcc -pg -o a.out sample.c
./a.out (gmon.outが作成される)
gprof ./a.out gmon.out
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
98.59 1.40 1.40 1 1.40 1.40 gauss_elim
1.41 1.42 0.02 randf
0.00 1.42 0.00 1 0.00 0.00 init_matrix
0.00 1.42 0.00 1 0.00 0.00 init_problem_random
0.00 1.42 0.00 1 0.00 0.00 init_vec
以下略
出力の見方の詳細については,同時に出力されている説明やマニュアルを参照されたい.
プロファイリングツール:Instruments
MacOSの開発環境であるXcodeに含まれる.XcodeのメニューからXcode→Open Developer Tools→Instrumentsで起動し,テンプレート選択画面からTime Profilerを選ぶ.使用方法については,ヘルプを参照されたい.(GUIなので容易であろう.)