Next: Autoconf, Previous: Debugging, Up: GMP Basics [Index]
プロファイラの配下でプログラムを実行すると,その中のどの部分で処理時間を食っているのか,どこを改善すべきかが判明します。GMPビルド時にプロファイリングの有無を指定するオプションは下記の通りです。
デフォルトではプロファイリングに関しては何も指定しません。
プログラムのメイン部分に-p
を付加してコンパイルすることで,prof
コマンドを使って,プログラムに埋め込まれたカウンタのサンプリングを行ってプロファイリング情報を取得できるようになります。GMPのアセンブラコードには大体,このために必要となるシンボルが入っています。
こういうやり方をすることで,通常のプログラム処理に干渉する手間を最小限にとどめることができますが,大概のシステムのサンプリング時間間隔は非常に長い(例えば10ミリ秒間隔)ので,長時間実行しないと正確な情報が掴めません。
システム標準のプロファイラprof
を利用可能にします。‘-p’はコンパイラのフラグ‘CFLAGS’に付加されます。
このオプションを指定することで,プログラムのカウント間隔の指定だけでなく,呼び出し回数のカウントができるようになり,一番呼び出される回数の多いルーチンの特定や,指定関数の平均処理時間を知ることができるようになります。
x86アセンブラコードはこのオプションをサポートしていますが,他のプロセッサ上では,アセンブラルーチンは‘-p’オプションナシでビルドした形になり,結果として呼び出し回数のカウントはできなくなります。
GNU/Linuxのようなシステムでは, ‘-p’は事実上‘-pg’と同義となり,下記で説明する‘--enable-profiling=gprof’を指定した方がいいでしょう。
gprof
が使えるようにビルドします。‘-pg’は
‘CFLAGS’に追加するフラグです。
このオプションは,呼び出し回数を行ったり,その調査間隔を指定したりするのに加えて,グラフを構成します。
これによって,異なる場所からの呼び出し回数を数えることができるようになります。
例えば,mpz_mul
関数とmpf_mul
関数からの,mpn_mul
関数の呼び出し回数を比較したいとします。
調査間隔が同じ場合,グラフなしではmpn_mul
関数で要する計算時間はまとめて積算され,それぞれの関数毎の呼び出し分を分離することはできなくなってしまいます。
x86アセンブラコードではこのオプションをサポートしています。他のプロセッサ上では,アセンブラルーチンは,‘-pg’オプションナシでコンパイルされ,関数呼び出し回数を数えることはできません。
x86系とm68k系のシステムでは‘-pg’ と ‘-fomit-frame-pointer’に互換性はありませんので,後者はデフォルトフラグからは除かれ,効率の悪いコードが生成される可能性があります。
ついでに言うと, ‘--enable-profiling=prof’オプション付きでビルドしたとしても,gprof
は利用可能にしておくべきでしょう。‘gprof -p’だけだとフラットプロファイルと呼びだし回数カウントが行えるようになりますが,‘gprof -q’を指定しないと呼び出しグラフを得ることはできません。
GCCのオプションである‘-finstrument-functions’を ‘CFLAGS’に追加します (see Options for Code Generation in Using the GNU Compiler Collection (GCC))。
このオプションは,関数の最初と最後に実行する特別な命令を追加できるようになります。これによって正確な時間計測と,呼び出しグラフ構造が判明します。
この命令は標準のシステムにはない機能ですので,下記のような外部ライブラリのサポートがないと使えません。
このオプションは,テストプログラムにリンクできるよう,GMPのconfiugre時に‘LIBS’に含めておく必要があります。
./configure --enable-profiling=instrument LIBS=-lfc
GNUシステム上では,Cライブラリはダミーの命令関数を提供しており,このオプションをつけてコンパイルしたプログラムはこれをリンクできるようになります。この場合は,アプリケーションのリンク時に正しいライブラリを指定するだけで済みます。
x86アセンブラコードはこのオプションをサポートしていますが,他のプロセッサのアセンブラコードは‘-finstrument-functions’オプションなしでコンパイルされるものと考えて下さい。