2011-12-30 15 views
18

Tutti parità di altri fattori (ad esempio livello di ottimizzazione), come si fa con i simboli di debug in un ELF o giù di lì influenzano: tempoIn che modo i simboli di debug influiscono sulle prestazioni di un eseguibile Linux compilato da GCC?

  1. carico.
  2. Ingombro memoria di runtime.
  3. Prestazioni di runtime?

E cosa si può fare per attenuare eventuali effetti negativi?

EDIT Ho visto questa domanda ma trovo la discussione non utile, in quanto il fattore di ottimizzazione del codice ha confuso il problema. Why does my code run slower with multiple threads than with a single thread when it is compiled for profiling (-pg)?

risposta

21

I simboli di debug si trovano in sezioni completamente diverse dalle sezioni di codice/dati. È possibile controllare con objdump:

$ objdump -h a.out 

a.out:  file format elf64-x86-64 

Sections: 
Idx Name   Size  VMA    LMA    File off Algn 
    0 .interp  0000001c 0000000000400200 0000000000400200 00000200 2**0 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
    1 .note.ABI-tag 00000020 000000000040021c 000000000040021c 0000021c 2**2 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
    2 .note.gnu.build-id 00000024 000000000040023c 000000000040023c 0000023c 2**2 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
    3 .hash   00000018 0000000000400260 0000000000400260 00000260 2**3 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
    4 .gnu.hash  0000001c 0000000000400278 0000000000400278 00000278 2**3 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
    5 .dynsym  00000048 0000000000400298 0000000000400298 00000298 2**3 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
    6 .dynstr  00000038 00000000004002e0 00000000004002e0 000002e0 2**0 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
    7 .gnu.version 00000006 0000000000400318 0000000000400318 00000318 2**1 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
    8 .gnu.version_r 00000020 0000000000400320 0000000000400320 00000320 2**3 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
    9 .rela.dyn  00000018 0000000000400340 0000000000400340 00000340 2**3 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
10 .rela.plt  00000018 0000000000400358 0000000000400358 00000358 2**3 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
11 .init   00000018 0000000000400370 0000000000400370 00000370 2**2 
        CONTENTS, ALLOC, LOAD, READONLY, CODE 
12 .plt   00000020 0000000000400388 0000000000400388 00000388 2**2 
        CONTENTS, ALLOC, LOAD, READONLY, CODE 
13 .text   000001c8 00000000004003b0 00000000004003b0 000003b0 2**4 
        CONTENTS, ALLOC, LOAD, READONLY, CODE 
14 .fini   0000000e 0000000000400578 0000000000400578 00000578 2**2 
        CONTENTS, ALLOC, LOAD, READONLY, CODE 
15 .rodata  00000004 0000000000400588 0000000000400588 00000588 2**2 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
16 .eh_frame_hdr 00000024 000000000040058c 000000000040058c 0000058c 2**2 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
17 .eh_frame  0000007c 00000000004005b0 00000000004005b0 000005b0 2**3 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
18 .ctors  00000010 0000000000600630 0000000000600630 00000630 2**3 
        CONTENTS, ALLOC, LOAD, DATA 
19 .dtors  00000010 0000000000600640 0000000000600640 00000640 2**3 
        CONTENTS, ALLOC, LOAD, DATA 
20 .jcr   00000008 0000000000600650 0000000000600650 00000650 2**3 
        CONTENTS, ALLOC, LOAD, DATA 
21 .dynamic  000001a0 0000000000600658 0000000000600658 00000658 2**3 
        CONTENTS, ALLOC, LOAD, DATA 
22 .got   00000008 00000000006007f8 00000000006007f8 000007f8 2**3 
        CONTENTS, ALLOC, LOAD, DATA 
23 .got.plt  00000020 0000000000600800 0000000000600800 00000800 2**3 
        CONTENTS, ALLOC, LOAD, DATA 
24 .data   00000010 0000000000600820 0000000000600820 00000820 2**3 
        CONTENTS, ALLOC, LOAD, DATA 
25 .bss   00000010 0000000000600830 0000000000600830 00000830 2**3 
        ALLOC 
26 .comment  00000039 0000000000000000 0000000000000000 00000830 2**0 
        CONTENTS, READONLY 
27 .debug_aranges 00000030 0000000000000000 0000000000000000 00000869 2**0 
        CONTENTS, READONLY, DEBUGGING 
28 .debug_pubnames 0000001b 0000000000000000 0000000000000000 00000899 2**0 
        CONTENTS, READONLY, DEBUGGING 
29 .debug_info 00000055 0000000000000000 0000000000000000 000008b4 2**0 
        CONTENTS, READONLY, DEBUGGING 
30 .debug_abbrev 00000034 0000000000000000 0000000000000000 00000909 2**0 
        CONTENTS, READONLY, DEBUGGING 
31 .debug_line 0000003b 0000000000000000 0000000000000000 0000093d 2**0 
        CONTENTS, READONLY, DEBUGGING 
32 .debug_str 00000026 0000000000000000 0000000000000000 00000978 2**0 
        CONTENTS, READONLY, DEBUGGING 
33 .debug_loc 0000004c 0000000000000000 0000000000000000 0000099e 2**0 
        CONTENTS, READONLY, DEBUGGING 

si possono vedere le sezioni in più (27 a 33). Queste sezioni non verranno caricate in fase di esecuzione, quindi non ci sarà alcuna penalità di prestazioni. Utilizzando gdb, è anche possibile esaminare in fase di esecuzione

$ gdb ./a.out 
(gdb) break main 
(gdb) run 
(gdb) info files 
// blah blah .... 
Local exec file: 
     `/home/kghost/a.out', file type elf64-x86-64. 
     Entry point: 0x4003b0 
     0x0000000000400200 - 0x000000000040021c is .interp 
     0x000000000040021c - 0x000000000040023c is .note.ABI-tag 
     0x000000000040023c - 0x0000000000400260 is .note.gnu.build-id 
     0x0000000000400260 - 0x0000000000400278 is .hash 
     0x0000000000400278 - 0x0000000000400294 is .gnu.hash 
     0x0000000000400298 - 0x00000000004002e0 is .dynsym 
     0x00000000004002e0 - 0x0000000000400318 is .dynstr 
     0x0000000000400318 - 0x000000000040031e is .gnu.version 
     0x0000000000400320 - 0x0000000000400340 is .gnu.version_r 
     0x0000000000400340 - 0x0000000000400358 is .rela.dyn 
     0x0000000000400358 - 0x0000000000400370 is .rela.plt 
     0x0000000000400370 - 0x0000000000400388 is .init 
     0x0000000000400388 - 0x00000000004003a8 is .plt 
     0x00000000004003b0 - 0x0000000000400578 is .text 
     0x0000000000400578 - 0x0000000000400586 is .fini 
     0x0000000000400588 - 0x000000000040058c is .rodata 
     0x000000000040058c - 0x00000000004005b0 is .eh_frame_hdr 
     0x00000000004005b0 - 0x000000000040062c is .eh_frame 
     0x0000000000600630 - 0x0000000000600640 is .ctors 
     0x0000000000600640 - 0x0000000000600650 is .dtors 
     0x0000000000600650 - 0x0000000000600658 is .jcr 
     0x0000000000600658 - 0x00000000006007f8 is .dynamic 
     0x00000000006007f8 - 0x0000000000600800 is .got 
     0x0000000000600800 - 0x0000000000600820 is .got.plt 
     0x0000000000600820 - 0x0000000000600830 is .data 
     0x0000000000600830 - 0x0000000000600840 is .bss 
// blah blah .... 

Quindi, l'unica pena è che avete bisogno di spazio su disco per memorizzare queste informazioni. È inoltre possibile utilizzare strip per rimuovere le informazioni di debug:

$ strip a.out 

Usa objdump per verificare di nuovo, vedrete la differenza.

EDIT:

Invece guardando sezioni, in realtà il caricatore caricamento del file elfo secondo la sua Program Header, che può essere visto da objdump -p. (Esempio seguente utilizza un diverso binario ELF)

$ objdump -p /bin/cat 

/bin/cat:  file format elf64-x86-64 

Program Header: 
    PHDR off 0x0000000000000040 vaddr 0x0000000000000040 paddr 0x0000000000000040 align 2**3 
     filesz 0x00000000000001f8 memsz 0x00000000000001f8 flags r-x 
    INTERP off 0x0000000000000238 vaddr 0x0000000000000238 paddr 0x0000000000000238 align 2**0 
     filesz 0x000000000000001c memsz 0x000000000000001c flags r-- 
    LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**21 
     filesz 0x00000000000078bc memsz 0x00000000000078bc flags r-x 
    LOAD off 0x0000000000007c28 vaddr 0x0000000000207c28 paddr 0x0000000000207c28 align 2**21 
     filesz 0x0000000000000678 memsz 0x0000000000000818 flags rw- 
DYNAMIC off 0x0000000000007dd8 vaddr 0x0000000000207dd8 paddr 0x0000000000207dd8 align 2**3 
     filesz 0x00000000000001e0 memsz 0x00000000000001e0 flags rw- 
    NOTE off 0x0000000000000254 vaddr 0x0000000000000254 paddr 0x0000000000000254 align 2**2 
     filesz 0x0000000000000044 memsz 0x0000000000000044 flags r-- 
EH_FRAME off 0x0000000000006980 vaddr 0x0000000000006980 paddr 0x0000000000006980 align 2**2 
     filesz 0x0000000000000274 memsz 0x0000000000000274 flags r-- 
    STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4 
     filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw- 
    RELRO off 0x0000000000007c28 vaddr 0x0000000000207c28 paddr 0x0000000000207c28 align 2**0 
     filesz 0x00000000000003d8 memsz 0x00000000000003d8 flags r-- 

Il programma intestazioni dicono quale segmento sarà caricato con ciò rwx bandiere, più sezioni con le stesse bandiere saranno fusi in un unico segmento.

BTW:

Il caricatore non si preoccupa sezioni durante il caricamento di file elfo, ma sarà più sezioni relative simboli per risolvere i simboli quando necessario.

+2

Si noti che l'attributo chiave di ogni sezione è 'ALLOC' - le sezioni .debug non hanno questo, che indica che non verranno caricati in fase di esecuzione (mediante l'esecuzione normale). Ho trovato maggiori informazioni qui: http://www.tortall.net/projects/yasm/manual/html/objfmt-elf-section.html – Justicle

-2

Si potrebbe voler guardare Why does my code run slower with multiple threads than with a single thread when it is compiled for profiling (-pg)? per una rapida spiegazione di come i simboli di debug potrebbero influenzare l'ottimizzazione.

per rispondere alle vostre 3 domande:

  1. tempo di caricamento sarà aumentata quando i simboli di debug sono presenti più di quando non è presente
  2. L'on-disk impronta sarà più grande
  3. Se si è compilato con lo zero ottimizzazione quindi non si perde davvero nulla. Se si imposta l'ottimizzazione, il codice ottimizzato sarà meno ottimizzato a causa dei simboli di debug.
+9

Sono abbastanza sicuro che # 3 non è vero; la presenza o l'assenza di simboli di debug non influisce sulla generazione del codice. (I simboli di debug possono essere inesatti o parzialmente non disponibili nei binari ottimizzati.) – duskwuff

+6

La risposta accettata alla domanda che si collega indica che il richiedente aveva _profiling_ attivato - questo ha una penalità di runtime. I simboli di debug no. – Mat

+1

Grazie - Non ho trovato quella particolare domanda utile in quanto la discussione è stata confusa con l'ottimizzazione. Nota che questa risposta contraddice direttamente tutti i tuoi punti http://stackoverflow.com/a/8676610/94239 – Justicle

Problemi correlati