kubo39's blog

ただの雑記です。

perfを使ってD言語のプロファイリング結果をみる

まず手元の /proc/sys/kernel/perf_event_paranoid を確認する。Ubuntuとかだと最弱設定になってるので変えとく。

$ cat /proc/sys/kernel/perf_event_paranoid
3
$ sudo sh -c 'echo 1 > /proc/sys/kernel/perf_event_paranoid'

普通に perf record にかける。

$ perf record dmd fib.d
[ perf record: Woken up 1 times to write data ]
[kernel.kallsyms] with build id ef8b1ed123757213c70bca103ce70b59825d9c11 not found, continuing without symbols
[ perf record: Captured and wrote 0.052 MB perf.data (1240 samples) ]

perf report で出力するときに ddemangle に食わせるとsymbol nameがdemangleされるので便利。

$ perf report| ddemangle| head -20
[kernel.kallsyms] with build id ef8b1ed123757213c70bca103ce70b59825d9c11 not found, continuing without symbols
# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 1K of event 'cycles:uppp'
# Event count (approx.): 706573056
#
# Overhead  Command   Shared Object            Symbol                                                                                                                                                                                                                                                
# ........  ........  .......................  ......................................................................................................................................................................................................................................................
#
    12.51%  ld        libbfd-2.30-system.so    [.] bfd_hash_lookup
     7.98%  ld        libc-2.27.so             [.] __gconv_transform_utf8_internal
     5.34%  dmd       dmd                      [.] void dmd.lexer.Lexer.scan(dmd.tokens.Token*)
     3.80%  ld        libc-2.27.so             [.] __strcmp_sse2_unaligned
     3.50%  ld        libc-2.27.so             [.] __mbsrtowcs_l
     3.32%  ld        x86_64-linux-gnu-ld.bfd  [.] walk_wild_section_general
     3.31%  ld        libc-2.27.so             [.] internal_fnwmatch
     3.25%  ld        x86_64-linux-gnu-ld.bfd  [.] walk_wild_section_specs3_wild2
     2.81%  ld        libc-2.27.so             [.] __strnlen_avx2

まあここまでは別によい。

dmd -profile と perf(oprofile) の使い分けってどうなの?みたいなの聞かれたときに dmd -profile はLinuxだとrbtsc命令使っててコア間同期がうんたら〜みたいな話をしてしまって、まあそれは間違いじゃないのだけれど、実際そもそもdmd -profileはtracing方式(すべてのDの関数コールにフックする)のに対しperfはsampling方式(タイマーの間隔を決めて現在のスタックの状態を収集してどの関数が統計的に多くよばれてるか)という違いがあり、用途によって使い分けられるという話をすべきだったなー、と思った。(長い)

でも大体のケースはperfでいいんじゃないのかな、みたいな。特にsampling方式だと実際に負荷がかかってる本番環境とかでも計測できるのが嬉しい。実はこのパスがめっちゃ呼ばれてる、みたいなのとかは開発環境じゃわからなかったりするので。