Profiling mit perf



  • Hallo,

    ich versuche gerade, mit den neuen perf-Tools Userspace-Programme zu profilen, aber ich komm noch nicht so ganz klar.

    Ich hab folgendes dummes Beispielprogramm:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void f(int i) {
    	if(i%23==0)
    		printf("%d\n", i*i);
    }
    
    int
    main (int argc, char *argv[])
    {
    	int i, j;
    	for (i=0; i < 1000000; ++i)
    		 if(i*i*i==i*i) f(i);
    
    	for (i=0; i < 10000; ++i)
    		for(j=0; j < 10000;++j)
    			if (j==i*i*i)
    				f(i);
    }
    
    > gcc -g -fno-omit-frame-pointer t.c
    > perf record -g -- ./a.out
    0
    0
    [ perf record: Woken up 1 times to write data ]
    [ perf record: Captured and wrote 0.180 MB perf.data (~7880 samples) ]
    > perf report | head -n 20
    # Events: 3K cycles
    #
    # Overhead  Command  Shared Object  Symbol
    # ........  .......  .............  ......
    #
        99.76%    a.out  a.out          [.] main
                  |
                  --- (nil)
    
         0.21%    a.out  [sco]          [k] 0x0000000108cb08
                  |
                  --- 0xc0089c28
                      0xc008a224
                      0xc004904c
                      0xc05ec6ac
                      (nil)
    
                  |
                  --- 0xc010c8d4
                      0xc010e334
    [...]
    > >perf annotate | cat
    
    ------------------------------------------------
     Percent |	Source code & Disassembly of a.out
    ------------------------------------------------
             :
             :
             :
             :	Disassembly of section .text:
             :
             :	00008410 <main>:
             :	                printf("%d\n", i*i);
             :	}
             :
             :	int
             :	main (int argc, char *argv[])
             :	{
        0.00 :	    8410:       e92d4800        push    {fp, lr}
        0.00 :	    8414:       e28db004        add     fp, sp, #4
        0.00 :	    8418:       e24dd010        sub     sp, sp, #16
        0.00 :	    841c:       e50b0010        str     r0, [fp, #-16]
        0.00 :	    8420:       e50b1014        str     r1, [fp, #-20]
             :	        int i, j;
             :	        for (i=0; i < 1000000; ++i)
        0.00 :	    8424:       e3a03000        mov     r3, #0
        0.00 :	    8428:       e50b3008        str     r3, [fp, #-8]
        0.00 :	    842c:       ea00000e        b       846c <main+0x5c>
             :	                 if(i*i*i==i*i) f(i);
        0.03 :	    8430:       e51b3008        ldr     r3, [fp, #-8]
        0.06 :	    8434:       e51b2008        ldr     r2, [fp, #-8]
        0.09 :	    8438:       e0030392        mul     r3, r2, r3
        0.00 :	    843c:       e51b2008        ldr     r2, [fp, #-8]
        0.48 :	    8440:       e0020293        mul     r2, r3, r2
        0.00 :	    8444:       e51b3008        ldr     r3, [fp, #-8]
        0.03 :	    8448:       e51b1008        ldr     r1, [fp, #-8]
        0.15 :	    844c:       e0030391        mul     r3, r1, r3
        0.24 :	    8450:       e1520003        cmp     r2, r3
        0.00 :	    8454:       1a000001        bne     8460 <main+0x50>
        0.00 :	    8458:       e51b0008        ldr     r0, [fp, #-8]
        0.00 :	    845c:       ebffffcd        bl      8398 <f>
             :
             :	int
             :	main (int argc, char *argv[])
             :	{
             :	        int i, j;
             :	        for (i=0; i < 1000000; ++i)
        0.03 :	    8460:       e51b3008        ldr     r3, [fp, #-8]
        0.09 :	    8464:       e2833001        add     r3, r3, #1
        0.00 :	    8468:       e50b3008        str     r3, [fp, #-8]
        0.03 :	    846c:       e51b2008        ldr     r2, [fp, #-8]
        0.00 :	    8470:       e59f3088        ldr     r3, [pc, #136]  ; 8500 <main+0xf0>
        0.06 :	    8474:       e1520003        cmp     r2, r3
        0.00 :	    8478:       daffffec        ble     8430 <main+0x20>
             :	                 if(i*i*i==i*i) f(i);
             :
             :	        for (i=0; i < 10000; ++i)
        0.00 :	    847c:       e3a03000        mov     r3, #0
        0.00 :	    8480:       e50b3008        str     r3, [fp, #-8]
        0.00 :	    8484:       ea000016        b       84e4 <main+0xd4>
             :	                for(j=0; j < 10000;++j)
        0.00 :	    8488:       e3a03000        mov     r3, #0
        0.00 :	    848c:       e50b300c        str     r3, [fp, #-12]
        0.00 :	    8490:       ea00000c        b       84c8 <main+0xb8>
             :	                        if (j==i*i*i)
        4.76 :	    8494:       e51b3008        ldr     r3, [fp, #-8]
        3.91 :	    8498:       e51b2008        ldr     r2, [fp, #-8]
       13.09 :	    849c:       e0030392        mul     r3, r2, r3
        0.00 :	    84a0:       e51b2008        ldr     r2, [fp, #-8]
       24.93 :	    84a4:       e0020293        mul     r2, r3, r2
        0.00 :	    84a8:       e51b300c        ldr     r3, [fp, #-12]
       21.51 :	    84ac:       e1520003        cmp     r2, r3
        0.00 :	    84b0:       1a000001        bne     84bc <main+0xac>
             :	                                f(i);
        0.00 :	    84b4:       e51b0008        ldr     r0, [fp, #-8]
        0.00 :	    84b8:       ebffffb6        bl      8398 <f>
             :	        int i, j;
             :	        for (i=0; i < 1000000; ++i)
             :	                 if(i*i*i==i*i) f(i);
             :
             :	        for (i=0; i < 10000; ++i)
             :	                for(j=0; j < 10000;++j)
        3.85 :	    84bc:       e51b300c        ldr     r3, [fp, #-12]
        8.45 :	    84c0:       e2833001        add     r3, r3, #1
        0.00 :	    84c4:       e50b300c        str     r3, [fp, #-12]
        4.30 :	    84c8:       e51b200c        ldr     r2, [fp, #-12]
        4.36 :	    84cc:       e59f3030        ldr     r3, [pc, #48]   ; 8504 <main+0xf4>
        9.54 :	    84d0:       e1520003        cmp     r2, r3
        0.00 :	    84d4:       daffffee        ble     8494 <main+0x84>
             :	{
             :	        int i, j;
             :	        for (i=0; i < 1000000; ++i)
             :	                 if(i*i*i==i*i) f(i);
             :
             :	        for (i=0; i < 10000; ++i)
        0.00 :	    84d8:       e51b3008        ldr     r3, [fp, #-8]
        0.00 :	    84dc:       e2833001        add     r3, r3, #1
        0.00 :	    84e0:       e50b3008        str     r3, [fp, #-8]
        0.00 :	    84e4:       e51b2008        ldr     r2, [fp, #-8]
        0.00 :	    84e8:       e59f3014        ldr     r3, [pc, #20]   ; 8504 <main+0xf4>
        0.00 :	    84ec:       e1520003        cmp     r2, r3
        0.00 :	    84f0:       daffffe4        ble     8488 <main+0x78>
             :	                for(j=0; j < 10000;++j)
             :	                        if (j==i*i*i)
             :	                                f(i);
             :	}
        0.00 :	    84f4:       e1a00003        mov     r0, r3
        0.00 :	    84f8:       e24bd004        sub     sp, fp, #4
        0.00 :	    84fc:       e8bd8800        pop     {fp, pc}
        0.00 :	    8500:       000f423f        .word   0x000f423f
        0.00 :	    8504:       0000270f        .word   0x0000270f
    

    Das ist zwar ganz nett, aber nicht so schrecklich nützlich ...

    Meine Frageliste:
    - Kann ich mit perf überhaupt sinnvoll Userspace debuggen? (Und C++?)
    - Kann mir report irgendwie die Symbolnamen auflösen? Also sowas wie report nur nicht mit (nil)?
    - Kann ich irgendwie etwas vergleichbares wie gprofs "Flat Profile" erzeugen? Bzw. wie kann ich Verbindungen zwischen Code und Profiler herstellen?
    - Muss ich evtl. irgendwelche (Software-)Events angeben um vernünftig arbeiten zu können?

    Wenn jemand Erfahrung mit dem Tool hat, würd es mich sehr freuen, wenn mir jemand helfen könnte.

    Danke und viele Grüße
    Daniel


Anmelden zum Antworten