2009-10-13 10 views
5

Posiadam bibliotekę C++, która generuje znacznie większy kod, którego naprawdę oczekiwałbym za to, co robi. Z mniej niż 50 000 linii źródłowych otrzymuję obiekty współdzielone, które mają prawie 4 MB, a archiwa statyczne przesuwają 9. Jest to problematyczne zarówno dlatego, że biblioteki binarne są dość duże, i, o wiele gorsze, nawet proste aplikacje łączące się z nimi zwykle zyskują od 500 do 1000 KB w rozmiarze kodu. Kompilowanie biblioteki za pomocą flag takich jak -Os pomaga w tym, ale nie za bardzo.Jakie są niektóre techniki i narzędzia do profilowania nadmiernego rozmiaru kodu w aplikacjach C/C++?

Eksperymentowałem również z poleceniem GCC -frepo (pomimo tego, że cała dokumentacja, którą widziałem sugeruje, że w systemie Linux collect2 mimo wszystko scali zduplikowane szablony) i jawne tworzenie szablonów na szablonach, które wydawały się "prawdopodobnie" często duplikowane , ale bez żadnego rzeczywistego skutku w obu przypadkach. Oczywiście mówię "prawdopodobnie", ponieważ, jak w przypadku każdego rodzaju profilowania, ślepe zgadywanie, takie jak to, jest prawie zawsze błędne.

Czy jest jakieś narzędzie, które ułatwia profilowanie rozmiaru kodu lub w jakiś inny sposób mogę się dowiedzieć, co zajmuje tak dużo miejsca, lub, ogólniej, innych rzeczy, które powinienem wypróbować? Coś, co działa pod Linuksem byłoby idealne, ale wezmę to, co mogę dostać.

Odpowiedz

7

Jeśli chcesz dowiedzieć się, co znajduje się w twoim pliku wykonywalnym, zapytaj swoich narzędzi. Włącz opcję link-map (lub -M) łącznika LD, aby utworzyć plik mapy pokazujący, co umieścił w pamięci i gdzie. Wykonanie tego dla statycznego połączonego przykładu jest prawdopodobnie bardziej pouczające.

Jeśli nie wywołujesz bezpośrednio ld, ale tylko za pomocą wiersza poleceń gcc, możesz przekazać konkretne opcje ld do ld z wiersza poleceń gcc, poprzedzając je -Wl,.

+0

To nie jest "-W1", to "-Wl" –

+0

@FX - Dzięki za spostrzeżenie. Naprawiłem to. –

1

Jedną z metod, która jest bardzo prosta, ale bardzo szybka, jest analiza rozmiaru plików obiektów. Nie cały kod w plikach obiektowych zostanie skompilowany do ostatecznego pliku binarnego, więc może być kilka fałszywych trafień, ale może dać dobre wrażenie, gdzie znajdą się punkty aktywne. Po znalezieniu największych plików obiektów można zagłębić się w nie za pomocą narzędzi takich jak objdump i nm.

2

W systemie Linux linker z pewnością łączy wiele instancji szablonów.

Upewnij się, że nie mierzysz plików binarnych debugowania (informacje debugowania mogą zająć więcej niż 75% ostatecznego rozmiaru binarnego).

Jedną z technik zmniejszania ostatecznego rozmiaru binarnego jest kompilacja z -ffunction-sections i -fdata-sections, a następnie połączenie z -Wl,--gc-sections.

Jeszcze większa redukcja (widzieliśmy 25%) może być możliwe, jeśli używasz rozwojowej wersji [gold][1] (nowy ELF-tylko łącznik, część binutils) i połączyć z -Wl,--icf

Inną użyteczną techniką jest zmniejszenie zestawu symboli, które są "eksportowane" przez biblioteki współdzielone (wszystko jest domyślnie eksportowane), albo poprzez __attribute__((visibility(...))), albo za pomocą skryptu linkera. Szczegóły here (patrz "Kontrola eksportu").

Powiązane problemy