perfでぺろぺろしていたら詰まった

perfという大変優秀なプロファイラがあります。どう優秀かというと
・gprofと違い、-pgなど付けなくとも既存のバイナリに対して実行できます
・バイナリに対して実行できるという事はあらゆる言語の実行を観察できます

sudo apt-get install linux-tools

まずこれで必要なツールは入ります。
試しに何かのパフォーマンスを見てみましょう

$ perf stat ruby -e'100000.times{|n|p n}'


実行にかかったCPUサイクル数、分岐の数、分岐予測ミス数、キャッシュ参照数、キャッシュミス数などがズラズラ出ます。IPCなども計算されてプログラムの性質がわかります。
これでは物足りない人は、自分の好みの通りにセッティングを変えることもできます。

$ perf list

で観測可能なモノのリストが表示されるので、その中から好きなものをコンマで繋いで例えば

$ perf stat -e cache-references,cache-misses,L1-dcache-loads,L1-dcache-load-misses,L1-dcache-stores,L1-dcache-store-misses,dTLB-loads,dTLB-load-misses ruby -e'100000.times{|n|p n}'

などと書けばキャッシュの中でもL1のヒット状況やTLBの様子なども観察できます。

perf statはお試し機能のようなモノで、実はperf recordとperf annotateがもっとプロファイラらしい細かい情報を提供してくれます。

$ perf record -e ./do.sh
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.372 MB perf.data (~16254 samples) ]

のように記録して

$ perf report

と打てばこのような画面。

また

$ perf annotate

で逆アセンブル結果と並べて観察できます。

実際に経過している時間と表示される場所とに誤差が出ますが、高速化のとても大きなヒントになります。
なので徹底的にperfで様々なパラメータを追いかけたいと考えるのは自然な流れなのですが…

$ perf record -e branches ./do.sh

Error: perfcounter syscall returned with -1 (Operation not supported)

Fatal: No hardware sampling interrupt available. No APIC? If so then you can boot the kernel with the "lapic" boot parameter to force-enable it.

などと出て計測できません。

APICというハードウェアカウンタがカーネルから使える状態になっていないようです。カーネルのboot parameterにlapicと付け加えろと言ってるようなので設定を編集します。

以下の事を実践すると環境を破壊する恐れがあります。自己責任でお願いします。

/etc/grub.d/10_linuxにて

cat << EOF
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
EOF

と、ヒアドキュメントっぽい書き方してる所があるので

cat << EOF
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro lapic ${args}
EOF

と書き換えます。
そして

$ sudo grub-mkconfig -o /boot/grub/grub.cfg

で、/etc/grub.d/*の情報をもとに/boot/grub/grub.cfgの中身を書き換えてくれます。
結果は

$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-2.6.35-28-generic-pae root=UUID=1602199c-46d4-47bb-afda-0c224c7eccb6 ro lapic quiet splash

のようにして見れます。lapicの文字が加わっているところを見るに大丈夫そうです。

そして

$ perf record -e branches ./do.sh

と打つと…

Error: perfcounter syscall returned with -1 (Operation not supported)

Fatal: No hardware sampling interrupt available. No APIC? If so then you can boot the kernel with the "lapic" boot parameter to force-enable it.

同じこと言われたー!orz

となったところで今日はここまでにします。