VA Linux Systems Japan株式会社

ホーム 検索 お問い合わせ

English

 
 

 

ホーム VA Tech.Top テックライブラリーTop プロファイル測定-1

update : 2007/11/30

 

index

Xen特集

テックライブラリ

プロファイル測定

 

1

測定ツールとその実装

2

oprofile

プレゼンライブラリ

イベントレポート

tips

VA Virtual-suite

仮想化に関するレポート販売

Xenを使ってみよう

Kernel対応障害解析サービス VA Quest

   
 
 


プロファイル測定

linux での代表的なプロファイル測定の実装を解説します。
関連して、マルチスレッドプログラムのプロファイル測定の注意点を述べます。

なお、gprof、oprofile の基本的な使い方は既知のものとし、本書では特に解説はいたしません。

測定ツールとその実装 - gprof

linux では gprof は glibc に付属するツールです。ここでは glibc-2.3.6 を使って説明します。

gprof によるプロファイル測定を行うには、 -pg コンパイルオプションをつけてプログラムをコンパイルします。
このことにより、プログラムに以下の処理が追加されます。

 

各関数の先頭からの mcount 関数の呼出し

プログラム起動時の setitimer() の実行

プログラム終了時の gmon.out の書き出し

 

各関数の先頭からの mcount 関数の呼出し

-pg オプションをつけてコンパイルすると、関数の先頭から mcount への呼出しが行われます。

例えば i386 アーキテクチャでは以下のようになります。

$ cat a.c
int
f(int a) {
    return a;
}

$ cc -pg -S a.c
$ cat a.s
    .file   "a.c"
    .text
.globl f
    .type   f, @function
f:
    pushl   %ebp
    movl    %esp, %ebp
    call    mcount
    movl    8(%ebp), %eax
    popl    %ebp
    ret
    .size   f, .-f
    .section        .note.GNU-stack,"",@progbits
    .ident  "GCC: (GNU) 3.3.5 (Debian 1:3.3.5-13)"

mcount の実体は glibc-2.3.6/gmon/mcount.c にあります。

_MCOUNT_DECL(frompc, selfpc) /* _mcount; may be static, inline, etc */

{

ここで、_MCOUNT_DECL となっているのは、この関数には呼出し元とその親のプログラムカウンタ(それぞれ selfpc、frompc)が渡される必要があり、アーキテクチャ依存のコードが必要になるため、アーキテクチャ毎の違いを吸収するためにマクロになっています。

この関数は、frompc と selfpc の組に対応するカウンタをインクリメントするので、各関数が何回、どこから呼ばれたかがわかります。

プログラム起動時の setitimer() の実行

プログラム起動時に

__monstartup ((u_long) TEXT_START, (u_long) &etext);

が実行されます。

__monstartup は gmon/gmon.c にあり、プロファイル測定用テーブルの初期化を行い、

__profil((void *) p->kcount, p->kcountsize, p->lowpc, s_scale);

によって、一定実行時間毎にプログラムカウンタの位置に対応するカウンタがインクリメントされるようになります。

profil は BSD 系 UNIX などではシステムコールですが、linux ではタイマ割り込みとシグナルハンドラを用いて実装されています。

__profil の定義は sysdeps/posix/profil.c にあり、
__setitimer(ITIMER_PROF, ...) を実行し、一定 CPU 実行時間毎に SIGPROF シグナルが発生するようになります。linux-2.6.11 以前では、この setitimer はスレッド毎なので、マルチスレッドプログラムでは、 gmon-helper.o※1などを使用して、スレッド毎に setitimer を実行する必要があります。

プログラム終了時の gmon.out の書き出し

atexit (&_mcleanup);

が実行され、プロセス終了時に _mcleanup から呼ばれる write_gmon 関数から上記のカウンタの値がファイルに書き出されます。

デフォルトの出力ファイル名は gmon.out ですが、環境変数 GMON_OUT_PREFIX で変更することができます。

_mcleanup は atexit を利用して呼ばれるので、プロセスの異常終了時には gmon.out は生成されません。

 

上記の3つの処理によって、以下の情報を取得することができます。

 

各関数の実行回数

コールグラフ

各関数の実行時間

 
 

※1

http://sam.zoy.org/writings/programming/gprof.html を参照してください。

 

次へ


 
 
本サイトの利用に関して 免責事項 コピーライト 個人情報保護方針

Copyright C VA Linux Systems Japan. All rights reserved.