2011-12-30 18 views
18

等於(例如優化級)所有其它因素,如何在具有一個ELF調試符號或SO影響:調試符號如何影響由GCC編譯的Linux可執行文件的性能?

  1. 載入時間。
  2. 運行時內存佔用。
  3. 運行性能?

可以做些什麼來減輕任何負面影響?

編輯 我見過這個問題,但我發現討論無益,因爲代碼優化因素已經混淆了那裏的問題。 Why does my code run slower with multiple threads than with a single thread when it is compiled for profiling (-pg)?

回答

21

調試符號位於代碼/數據部分完全不同的部分。您可以用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 

您可以看到額外的部分(27到33)。這些部分不會在運行時加載,所以不會有任何性能損失。使用gdb,你也可以在運行時

$ 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 .... 

檢查它們所以,唯一的代價是需要額外的磁盤空間來存儲這些信息。您還可以使用strip刪除調試信息:

$ strip a.out 

使用objdump檢查一遍,你會看到其中的差別。

編輯:

而是尋找部分,實際上裝載機根據其Program Header,可以通過objdump -p可以看到加載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-- 

程序頭告訴哪個段將與什麼RWX標誌被加載,具有相同的標誌的多個部分將被合併到一個單一的段。

BTW:

加載器加載ELF文件時,不會在意的部分,但它看起來幾個符號相關的部分需要時解析符號。

+2

請注意,每個部分的鍵屬性都是'ALLOC' - .debug部分沒有這個,表示它們不會在運行時加載(通過正常執行)。我在這裏找到更多信息:http://www.tortall.net/projects/yasm/manual/html/objfmt-elf-section.html – Justicle 2012-01-02 18:33:09

-2

您可能想看看Why does my code run slower with multiple threads than with a single thread when it is compiled for profiling (-pg)?以便快速瞭解調試符號如何影響優化。

要回答你的3個問題:當調試符號都存在過當不存在

  • 磁盤上的佔地面積將更大
  • 如果零編譯

    1. 加載時間將增加優化,那麼你真的沒有失去。如果您設置了優化,則由於調試符號的原因,優化後的代碼將不會優化。
  • +9

    我很確定#3是不正確的;調試符號的存在或不存在不影響代碼生成。 (在優化的二進制文件中,調試符號可能只是不精確或部分不可用。) – duskwuff 2011-12-30 05:44:59

    +6

    對於您鏈接的問題的接受答案指出提交者打開了_profiling_ - 這會導致運行時損失。調試符號不。 – Mat 2011-12-30 07:27:52

    +1

    謝謝 - 由於討論與優化混淆,我沒有發現這個特別的問題很有用。請注意,這個答案直接矛盾所有你的觀點http://stackoverflow.com/a/8676610/94239 – Justicle 2012-01-02 00:10:47

    相關問題