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のマニュアルを参照してください。

表示
個人用ツール
Open Source Projects