Linux カーネルプロファイリング
このドキュメントでは組込み Linux 開発用 CPU ボード Bishop でカーネルレベルのプロファイリングを行う手順として、 最もシンプルな readprofile と今後 Linux カーネルの標準的なプロファイラとなると思われる OProfile の 簡単な使用方法を紹介します。
- 1. readprofile
- 1.1. 概要
- 1.2. 使用方法
- 1.2.1. readprofile のインストール
- 1.2.2. Linux カーネルのビルド
- 1.2.3. Linux カーネルを起動
- 1.2.4. readprofile の基本的な使い方
- 1.3. プロファイリングバッファのサイズについて
- 2. OProfile
- 2.1. 概要
- 2.2. 使用方法
- 2.2.1. Linux カーネルのビルド
- 2.2.2. Linux カーネルを起動
- 2.2.3. OProfile のインストール
- 2.2.4. OProfile の基本的な使い方
- 3. 関連リンク
1. readprofile
1.1. 概要
Linuxカーネルに標準で含まれるシンプルなプロファイラ (kernel/profile.c) は tick 毎に実行アドレスをカーネル内部のプロファイリングバッファに保持します。このバッファは仮想ファイル /proc/profile を通じてユーザ空間からアクセスできますが、/proc/profile はバイナリファイルであるためそのままでは読めません。readprofile は /proc/profile を可読化するために使用されるツールです。
1.2. 使用方法
1.2.1. readprofile のインストール
readprofile コマンドをインストールしてください。Debian の場合、readprofile は util-linux パッケージに含まれます。
# aptitude install util-linux開発ホストとターゲットの両方にインストールしておくと便利です。
1.2.2. Linux カーネルのビルド
CONFIG_PROFILING を有効にしてカーネルをビルドします。
$ cd linux-2.6.26.8-pylone0 $ make ARCH=arm menuconfig General setup ---> [*] Profiling support (EXPERIMENTAL) $ make ARCH=arm CROSS_COMPILE=arm-linux-gnu- uImage
uImage と同時に作られる System.map も後で使用します。
1.2.3. Linux カーネルを起動
プロファイラを有効にするカーネル起動パラメータ profile を追加して前節でビルドしたカーネルを起動します。
U-Boot のモニタコマンドでカーネルパラメータを追加する例:
Bishop # setenv bootargs console=.... profile=2profile= に渡される数値が大きい程プロファイラのバッファが小さくなります。
起動後に /proc/profile が存在すれば、カーネルのプロファイラが有効になっています。
1.2.4. readprofile の基本的な使い方
-m オプションで System.map を指定します。
bishop:~# readprofile -m /PATH/TO/System.map/proc/profile を可読化したものが出力されます。
bishop:~# readprofile
3 start_kernel 0.0045
1 tcp_init 0.0014
18 calibrate_delay 0.0464
19 do_DataAbort 0.1187
7 __dabt_svc 0.0729
[...]
1 down_write 0.0500
1 down_read 0.0500
4 __down_write_nested 0.0182
1 __down_write 0.0417
0 *unknown*
15409 total 0.0047
1番目のカラムが tick 毎にサンプリングされた tick 回数で、 2番目のカラムが関数名です。 3番目のカラムは正規化された負荷で、サンプリングされた tick 回数と関数の長さの比率です。[1]
-p オプションで /proc/profile を変更できますので、ターゲット側のプロファイリングをホスト側で見たい場合は
ターゲット
bishop:~# cat /proc/profile > profile-shapshotホスト:
# readprofile -p profile-snapshot -m /PATH/TO/System.mapのようにすればよいでしょう。
また、-r オプションでプロファイラのバッファをリセットできるので、特定のプログラム (your_program) 実行中のプロファイリングしたい場合は
bishop:~# readprofile -r bishop:~# your_program bishop:~# readprofile -m /PATH/TO/System.map
とすることもできます。
さらに詳しい使い方については readprofile(1) を参照してください。
1.3. プロファイリングバッファのサイズについて
プロファイラのバッファは kernel/profile.c の profile_init() で確保されます。
void __init profile_init(void)
{
if (!prof_on)
return;
/* only text is profiled */
prof_len = (_etext - _stext) >> prof_shift;
prof_buffer = alloc_bootmem(prof_len*sizeof(atomic_t));
}prof_shift は profile= パラメータで渡された数値です。
_etext と _stext は以下のようにすれば知ることができます。
$ arm-linux-gnu-objdump -t vmlinux | grep _[es]text
c0376000 g *ABS* 00000000 _etext
c0008000 g .text.head 00000000 _stext
Linux/ARM の場合、上記の _etext, _stext で profile=2 とするとバッファサイズは
バッファサイズ = ((_etext - _stext) >> prof_shift) * sizeof(struct atomic_t)
= ((0xc0376000 - 0xc0008000) >> 2) * 4
= 0x36e000
(約3.5MB)となります。
/proc/profile のファイルサイズはこれと同じになっている筈です。
2. OProfile
2.1. 概要
OProfile は Linux カーネルに標準で含まれるオーバーヘッドが少ないシステムワイドなプロファイラです。 gprof などのユーザ空間プロファイラと違い、カーネル空間も含めたプロファイリングが可能です。
2.2. 使用方法
2.2.1. Linux カーネルのビルド
CONFIG_PROFILING と CONFIG_OPROFILE を有効にしてカーネルをビルドします。
$ cd linux-2.6.26.8-pylone0 $ make ARCH=arm menuconfig General setup ---> [*] Profiling support (EXPERIMENTAL) [ ] Activate markers <*> OProfile system profiling (EXPERIMENTAL) $ make ARCH=arm CROSS_COMPILE=arm-linux-gnu- uImage
カーネル空間のプロファイリングを行うのであれば、uImage だけでなく vmlinux も後で使用します。
2.2.2. Linux カーネルを起動
CONFIG_OPROFILE を有効にしたカーネルで起動します。OProfile だけを使うのであれば起動パラメータを追加する必要はありません。
2.2.3. OProfile のインストール
ターゲットの /etc/apt/sources.list に以下の apt-line を追加します。
deb http://downloads.pylone.jp/bishop/deb/etch ./
oprofile-common パッケージ をインストールします。
bishop:~# aptitude update bishop:~# aptitude install oprofile-common
株式会社パイロンが etch の oprofile パッケージを ARM 用にリビルドした非公式パッケージです。このパッケージに関する質問を Debian プロジェクトにすることはご遠慮ください。
2.2.4. OProfile の基本的な使い方
a.out 実行中のプロファイリングを行うには opcontrol コマンドを以下のように実行します。
bishop:~# opcontrol --vmlinux=/PATH/TO/vmlinux bishop:~# opcontrol --reset bishop:~# opcontrol --start ; a.out ; opcontrol --stop
カーネル空間のプロファイリングが不要であれば --vmlinux= の代わりに --no-vmlinux を指定します。
bishop:~# opcontrol --no-vmlinuxプロファイルの結果を見るためには opreport コマンドを使用します。
bishop:~# opreport
CPU: CPU with timer interrupt, speed 0 MHz (estimated)
Profiling through timer interrupt
TIMER:0|
samples| %|
------------------
3475 89.1940 a.out
356 9.1376 vmlinux
34 0.8727 bash
17 0.4363 libc-2.3.6.so
12 0.3080 ld-2.3.6.so
1 0.0257 mktemp
1 0.0257 oprofiled
上記の通りオプション無しで opreport を実行すると各プロセス毎のサンプリング数で表示されます。Bishop の S3C2440 を含めハードウェアパフォーマンスモニタをサポートしていない CPU の場合はタイマ割込みによるサンプリングとなり、粒度は CONFIG_HZ によって変わります。
-l オプションをつけて opreport を実行すればプロセス毎ではなくシンボル名毎の表示になります。
bishop:~# opreport -l
CPU: CPU with timer interrupt, speed 0 MHz (estimated)
Profiling through timer interrupt
samples % app name symbol name
3473 89.1427 a.out function_heavy
185 4.7485 vmlinux default_idle
34 0.8727 bash (no symbols)
17 0.4363 libc-2.3.6.so (no symbols)
16 0.4107 vmlinux $a
16 0.4107 vmlinux update_mmu_cache
[...]
1 0.0257 vmlinux write_cache_pages
1 0.0257 vmlinux xprt_release_rqst_cong
1 0.0257 vmlinux xprt_reserve_xprt_cong
上記の libc-2.3.6.so のように実行ファイルにシンボルが含まれていない場合は (no symbols) と表示されます。
実行ファイルを指定することで特定のプログラムのみを表示させることもできます。
bishop:~# opreport -l a.out
CPU: CPU with timer interrupt, speed 0 MHz (estimated)
Profiling through timer interrupt
samples % symbol name
3473 99.9424 function_heavy
1 0.0288 function_light
1 0.0288 function_nop
シンボル情報付きの実行ファイルとソースコードがあれば、opannotate コマンドでプロファイリング結果とソースを関連付けて表示することもできます。
Cのソースと関連付けて表示:
bishop:~# opannotate -s a.outアセンブリと関連付けて表示:
bishop:~# opannotate -a a.outCとアセンブリの表示をミックス:
bishop:~# opannotate -sa a.outさらに詳しい使い方については OProfile のマニュアルを参照してください。
3. 関連リンク
- ^ the normalized `load' of the procedure, calculated as a ratio between the number of ticks and the length of the procedure
著作権と免責
Copyright © 2012 Pylone, Inc.
この文書の著作権は株式会社パイロンが保有します。
この文書は「現状のまま(as is)」で提供され、明示的であるかどうかを問わず、内容についてなんら保証するものではありません。
この文書には、技術的な誤り、誤植、不適格な表現や未完成部分等を含む可能性があります。従って、この文書は予告無しに追加、変更、削除される可能性があります。
この文書は「クリエイティブ・コモンズ-表示-2.1-日本 以降」(CC-by-2.1 or later) の下で配布されています。