OProfileを使ってCPUプロファイリングをとる
出典: PS3 Linux Information Site / Cell/B.E.のパワーを体験しよう
目次 |
OProfileとは
Linuxシステムで使えるプロファイラです。
カーネル内で発生したイベントごとにサンプリングを行うので、カーネル内も含めたシステム全体のプロファイルを取れるのと、ハードウェアパフォーマンスモニタの値を取得できるのが特徴です。
ハードウェアパフォーマンスモニタが実装されていないシステム上でも、タイマ割り込みごとのサンプリングが利用できます。 このタイマ割り込みを使ったプロファイラはアーキテクチャに依存しないため、PS3 Linuxでも使用することが可能です。
なお、以下の解説は、バージョン0.9.1をもとにしています。
OProfileのインストール
OProfileを使うには、OProfileツールのインストールと、Linuxカーネルに含まれるOProfileモジュールのコンパイルが必要です。
OProfileツールは Fedora、もしくはFedora Coreシステムでは yum を使ってインストールすることができます。
$ yum install oprofile
LinuxのOProfileモジュールは、カーネルの CONFIG_PROFILING と CONFIG_OPROFILE を有効にするとコンパイルされます。
make menuconfig する場合は、"Instrumentation Support" の "Profiling Support" と "Oprofile system profiling" を有効にします。
Instrumentation Support --->
[*] Profiling support (EXPERIMENTAL)
<M> OProfile system profiling (EXPERIMENTAL)
"OPprofile for Cell Broadband Engine"はパフォーマンスモニタが実装されていないPS3上では使えません。無効にしてください。
カーネルをコンパイルしてインストールしたあと再起動してください。カーネルのコンパイルについては、Fedora 7のカーネルを再構築するを参考にしてください。
OProfileの使いかた
OProfileの基本的な操作には以下のものがあります。それぞれ、opcontrolコマンドにパラメータを渡すことで実行できます。
- vmlinuxの指定 (--vmlinx=<image path>)
- OProfileデーモンの開始 (--start-daemon)
- OProfileデーモンの終了 (--shutdown)
- プロファイリングの開始 (--start)
- プロファイリングの終了 (--stop)
- プロファイル結果のダンプ (--dump)
- プロファイル結果の消去 (--reset)
ダンプした結果は、opreportを使うと見ることができます。その他の操作については、OProfileのマニュアルを参照してください。yumを使ってインストールした場合、マニュアルは/usr/share/doc/oprofile-0.9.1/oprofile.htmlにあります。
基本的な使いかたは以下のようになります。(opcontrol はルート権限がある状態で実行してください)
$ opcontrol --vmlinux=/boot/vmliux.bin (利用中のカーネルイメージを指定) $ opcontrol --reset (以前のプロファイル結果を消す) $ opcontrol --start-daemon (デーモンを開始) $ opcontrol --start; target_program ; opcontrol --stop (target_programを測定) $ opcontrol --dump (プロファイル結果をダンプ)
これで target_program のプロファイルを行うことができます。
プロファイル結果の解析
opreport を実行すると、ダンプされた結果を見ることができます。ここでプロファイルの測定対象としたプログラムはこれです。Media:Oprofile-target.tar.gz
オプション無しでopreportを実行した場合、実行バイナリ、共有ライブラリ、カーネルのどのファイル内で時間を費やしたかが表示されます
$ opreport (プロファイル結果の参照)
CPU: CPU with timer interrupt, speed 0 MHz (estimated)
Profiling through timer interrupt
TIMER:0|
samples| %|
------------------
1970 58.5787 vmlinux-2.6.23-rc6-ga798b236
1344 39.9643 a.out
17 0.5055 libc-2.5.so
11 0.3271 libfb.so
5 0.1487 ld-2.5.so
4 0.1189 bash
4 0.1189 mlterm
2 0.0595 oprofile
2 0.0595 Xorg
1 0.0297 oprofiled
1 0.0297 libX11.so.6.2.0
1 0.0297 libXfont.so.1.4.1
1 0.0297 wmiir
サンプリングはタイマ割り込みごとに行われます。周期はカーネルの設定値によります。PS3の通常のカーネルでは、周期は250Hzに設定されています(CONFIG_HZ_250が設定されています)。
サンプリングはハードウェアスレッドごとに行なわれるため、PS3の場合サンプル数は、2スレッド分の値になります。上の場合、半分以上の時間がカーネル内で費やされているのは、片方のスレッドがほとんど停止しているためだと考えられます。
プロファイルの詳細を知りたい場合は、opreportに-lオプションを与えることで、関数ごとの値を見ることができます。ただし、実行バイナリにシンボルが残っているバイナリに限ります。
$ opreport -l warning: /oprofile could not be found. warning: /usr/bin/Xorg could not be read. CPU: CPU with timer interrupt, speed 0 MHz (estimated) Profiling through timer interrupt samples % app name symbol name 1842 54.7725 vmlinux-2.6.23-rc6-ga798b236 .local_irq_restore 665 19.7740 a.out func3() 451 13.4106 a.out func2() 228 6.7797 a.out func1() 74 2.2004 vmlinux-2.6.23-rc6-ga798b236 ._lv1_gpu_context_attribute 11 0.3271 libfb.so (no symbols) 7 0.2081 vmlinux-2.6.23-rc6-ga798b236 .unmap_vmas 4 0.1189 bash (no symbols) 4 0.1189 vmlinux-2.6.23-rc6-ga798b236 ._raw_spin_lock 3 0.0892 libc-2.5.so malloc (... snip ...) (警告はXorgとoprofileのシンボルファイルが読めないために出ている警告です。Xorgをプロファイルするのでなければ問題ありません)
opreport の引数に実行ファイルのパスを渡すと特定の実行ファイルのサンプル結果のみを見ることができます
$ opreport -l a.out CPU: CPU with timer interrupt, speed 0 MHz (estimated) Profiling through timer interrupt samples % symbol name 665 49.4792 func3() 451 33.5565 func2() 228 16.9643 func1()
a.out内では、func3に多くの時間を費やしていることがわかります。
opannotateを使うと、プログラムとプロファイル結果を並べて表示することができます。-a(--assembly)オプションを与えると、アセンブリとの対応を見ることができます。
$ opannotate -a a.out
:100016fc: b 10001734 <_Z5func3v+0x54>
:10001700: li r0,0
:10001704: stw r0,8(r31)
:10001708: b 1000171c <_Z5func3v+0x3c>
53 3.9435 :1000170c: sync
487 36.2351 :10001710: lwz r9,8(r31)
5 0.3720 :10001714: addi r0,r9,1
5 0.3720 :10001718: stw r0,8(r31)
8 0.5952 :1000171c: lwz r0,8(r31)
100 7.4405 :10001720: cmpwi cr7,r0,2999
7 0.5208 :10001724: ble+ cr7,1000170c <_Z5func3v+0x2c>
:10001728: lwz r9,12(r31)
:1000172c: addi r0,r9,1
(... snip ...)
実行ファイルにデバッグ情報が残っている場合、-s(--source)オプションを与える、ソースとプロファイル結果の対応を見ることができます。
$ opannotate -s a.out
(... snip ...)
:#include <iostream>
:using namespace std;
:
:void func1 () /* func1() total: 228 16.9643 */
:{
: for (int i = 0; i < 10000; i++)
203 15.1042 : for (int j = 0; j < 1000; j++)
25 1.8601 : asm volatile ("sync");
:}
:void func2 () /* func2() total: 451 33.5565 */
:{
: for (int i = 0; i < 10000; i++)
409 30.4315 : for (int j = 0; j < 2000; j++)
(... snip ...)
この他にも、CPUごと、スレッドごとにサンプル結果を集計する機能(opcontrol -p=...)や、サンプル結果をgprof互換のデータにして出力する機能(opgprof)などがあります。詳しくはOProfileのマニュアルを参照してください。
