Back to home page

OSCL-LXR

 
 

    


0001 
0002                 ------------------------------
0003                 ****** perf by examples ******
0004                 ------------------------------
0005 
0006 [ From an e-mail by Ingo Molnar, https://lore.kernel.org/lkml/20090804195717.GA5998@elte.hu ]
0007 
0008 
0009 First, discovery/enumeration of available counters can be done via
0010 'perf list':
0011 
0012 titan:~> perf list
0013   [...]
0014   kmem:kmalloc                             [Tracepoint event]
0015   kmem:kmem_cache_alloc                    [Tracepoint event]
0016   kmem:kmalloc_node                        [Tracepoint event]
0017   kmem:kmem_cache_alloc_node               [Tracepoint event]
0018   kmem:kfree                               [Tracepoint event]
0019   kmem:kmem_cache_free                     [Tracepoint event]
0020   kmem:mm_page_free                        [Tracepoint event]
0021   kmem:mm_page_free_batched                [Tracepoint event]
0022   kmem:mm_page_alloc                       [Tracepoint event]
0023   kmem:mm_page_alloc_zone_locked           [Tracepoint event]
0024   kmem:mm_page_pcpu_drain                  [Tracepoint event]
0025   kmem:mm_page_alloc_extfrag               [Tracepoint event]
0026 
0027 Then any (or all) of the above event sources can be activated and
0028 measured. For example the page alloc/free properties of a 'hackbench
0029 run' are:
0030 
0031  titan:~> perf stat -e kmem:mm_page_pcpu_drain -e kmem:mm_page_alloc
0032  -e kmem:mm_page_free_batched -e kmem:mm_page_free ./hackbench 10
0033  Time: 0.575
0034 
0035  Performance counter stats for './hackbench 10':
0036 
0037           13857  kmem:mm_page_pcpu_drain
0038           27576  kmem:mm_page_alloc
0039            6025  kmem:mm_page_free_batched
0040           20934  kmem:mm_page_free
0041 
0042     0.613972165  seconds time elapsed
0043 
0044 You can observe the statistical properties as well, by using the
0045 'repeat the workload N times' feature of perf stat:
0046 
0047  titan:~> perf stat --repeat 5 -e kmem:mm_page_pcpu_drain -e
0048    kmem:mm_page_alloc -e kmem:mm_page_free_batched -e
0049    kmem:mm_page_free ./hackbench 10
0050  Time: 0.627
0051  Time: 0.644
0052  Time: 0.564
0053  Time: 0.559
0054  Time: 0.626
0055 
0056  Performance counter stats for './hackbench 10' (5 runs):
0057 
0058           12920  kmem:mm_page_pcpu_drain    ( +-   3.359% )
0059           25035  kmem:mm_page_alloc         ( +-   3.783% )
0060            6104  kmem:mm_page_free_batched  ( +-   0.934% )
0061           18376  kmem:mm_page_free          ( +-   4.941% )
0062 
0063     0.643954516  seconds time elapsed   ( +-   2.363% )
0064 
0065 Furthermore, these tracepoints can be used to sample the workload as
0066 well. For example the page allocations done by a 'git gc' can be
0067 captured the following way:
0068 
0069  titan:~/git> perf record -e kmem:mm_page_alloc -c 1 ./git gc
0070  Counting objects: 1148, done.
0071  Delta compression using up to 2 threads.
0072  Compressing objects: 100% (450/450), done.
0073  Writing objects: 100% (1148/1148), done.
0074  Total 1148 (delta 690), reused 1148 (delta 690)
0075  [ perf record: Captured and wrote 0.267 MB perf.data (~11679 samples) ]
0076 
0077 To check which functions generated page allocations:
0078 
0079  titan:~/git> perf report
0080  # Samples: 10646
0081  #
0082  # Overhead          Command               Shared Object
0083  # ........  ...............  ..........................
0084  #
0085     23.57%       git-repack  /lib64/libc-2.5.so
0086     21.81%              git  /lib64/libc-2.5.so
0087     14.59%              git  ./git
0088     11.79%       git-repack  ./git
0089      7.12%              git  /lib64/ld-2.5.so
0090      3.16%       git-repack  /lib64/libpthread-2.5.so
0091      2.09%       git-repack  /bin/bash
0092      1.97%               rm  /lib64/libc-2.5.so
0093      1.39%               mv  /lib64/ld-2.5.so
0094      1.37%               mv  /lib64/libc-2.5.so
0095      1.12%       git-repack  /lib64/ld-2.5.so
0096      0.95%               rm  /lib64/ld-2.5.so
0097      0.90%  git-update-serv  /lib64/libc-2.5.so
0098      0.73%  git-update-serv  /lib64/ld-2.5.so
0099      0.68%             perf  /lib64/libpthread-2.5.so
0100      0.64%       git-repack  /usr/lib64/libz.so.1.2.3
0101 
0102 Or to see it on a more finegrained level:
0103 
0104 titan:~/git> perf report --sort comm,dso,symbol
0105 # Samples: 10646
0106 #
0107 # Overhead          Command               Shared Object  Symbol
0108 # ........  ...............  ..........................  ......
0109 #
0110      9.35%       git-repack  ./git                       [.] insert_obj_hash
0111      9.12%              git  ./git                       [.] insert_obj_hash
0112      7.31%              git  /lib64/libc-2.5.so          [.] memcpy
0113      6.34%       git-repack  /lib64/libc-2.5.so          [.] _int_malloc
0114      6.24%       git-repack  /lib64/libc-2.5.so          [.] memcpy
0115      5.82%       git-repack  /lib64/libc-2.5.so          [.] __GI___fork
0116      5.47%              git  /lib64/libc-2.5.so          [.] _int_malloc
0117      2.99%              git  /lib64/libc-2.5.so          [.] memset
0118 
0119 Furthermore, call-graph sampling can be done too, of page
0120 allocations - to see precisely what kind of page allocations there
0121 are:
0122 
0123  titan:~/git> perf record -g -e kmem:mm_page_alloc -c 1 ./git gc
0124  Counting objects: 1148, done.
0125  Delta compression using up to 2 threads.
0126  Compressing objects: 100% (450/450), done.
0127  Writing objects: 100% (1148/1148), done.
0128  Total 1148 (delta 690), reused 1148 (delta 690)
0129  [ perf record: Captured and wrote 0.963 MB perf.data (~42069 samples) ]
0130 
0131  titan:~/git> perf report -g
0132  # Samples: 10686
0133  #
0134  # Overhead          Command               Shared Object
0135  # ........  ...............  ..........................
0136  #
0137     23.25%       git-repack  /lib64/libc-2.5.so
0138                 |
0139                 |--50.00%-- _int_free
0140                 |
0141                 |--37.50%-- __GI___fork
0142                 |          make_child
0143                 |
0144                 |--12.50%-- ptmalloc_unlock_all2
0145                 |          make_child
0146                 |
0147                  --6.25%-- __GI_strcpy
0148     21.61%              git  /lib64/libc-2.5.so
0149                 |
0150                 |--30.00%-- __GI_read
0151                 |          |
0152                 |           --83.33%-- git_config_from_file
0153                 |                     git_config
0154                 |                     |
0155    [...]
0156 
0157 Or you can observe the whole system's page allocations for 10
0158 seconds:
0159 
0160 titan:~/git> perf stat -a -e kmem:mm_page_pcpu_drain -e
0161 kmem:mm_page_alloc -e kmem:mm_page_free_batched -e
0162 kmem:mm_page_free sleep 10
0163 
0164  Performance counter stats for 'sleep 10':
0165 
0166          171585  kmem:mm_page_pcpu_drain
0167          322114  kmem:mm_page_alloc
0168           73623  kmem:mm_page_free_batched
0169          254115  kmem:mm_page_free
0170 
0171    10.000591410  seconds time elapsed
0172 
0173 Or observe how fluctuating the page allocations are, via statistical
0174 analysis done over ten 1-second intervals:
0175 
0176  titan:~/git> perf stat --repeat 10 -a -e kmem:mm_page_pcpu_drain -e
0177    kmem:mm_page_alloc -e kmem:mm_page_free_batched -e
0178    kmem:mm_page_free sleep 1
0179 
0180  Performance counter stats for 'sleep 1' (10 runs):
0181 
0182           17254  kmem:mm_page_pcpu_drain    ( +-   3.709% )
0183           34394  kmem:mm_page_alloc         ( +-   4.617% )
0184            7509  kmem:mm_page_free_batched  ( +-   4.820% )
0185           25653  kmem:mm_page_free          ( +-   3.672% )
0186 
0187     1.058135029  seconds time elapsed   ( +-   3.089% )
0188 
0189 Or you can annotate the recorded 'git gc' run on a per symbol basis
0190 and check which instructions/source-code generated page allocations:
0191 
0192  titan:~/git> perf annotate __GI___fork
0193  ------------------------------------------------
0194   Percent |      Source code & Disassembly of libc-2.5.so
0195  ------------------------------------------------
0196           :
0197           :
0198           :      Disassembly of section .plt:
0199           :      Disassembly of section .text:
0200           :
0201           :      00000031a2e95560 <__fork>:
0202  [...]
0203      0.00 :        31a2e95602:   b8 38 00 00 00          mov    $0x38,%eax
0204      0.00 :        31a2e95607:   0f 05                   syscall
0205     83.42 :        31a2e95609:   48 3d 00 f0 ff ff       cmp    $0xfffffffffffff000,%rax
0206      0.00 :        31a2e9560f:   0f 87 4d 01 00 00       ja     31a2e95762 <__fork+0x202>
0207      0.00 :        31a2e95615:   85 c0                   test   %eax,%eax
0208 
0209 ( this shows that 83.42% of __GI___fork's page allocations come from
0210   the 0x38 system call it performs. )
0211 
0212 etc. etc. - a lot more is possible. I could list a dozen of
0213 other different usecases straight away - neither of which is
0214 possible via /proc/vmstat.
0215 
0216 /proc/vmstat is not in the same league really, in terms of
0217 expressive power of system analysis and performance
0218 analysis.
0219 
0220 All that the above results needed were those new tracepoints
0221 in include/tracing/events/kmem.h.
0222 
0223         Ingo
0224 
0225