2010-01-08 17 views
7

Mam pytanie dotyczące czasu ładowania bibliotek współdzielonych a statycznych.Czas ładowania bibliotek współdzielonych a bibliotek statycznych

Załóżmy, że mam plik wykonywalny foo.exe, który używa liba, libb, libc. Również w danym momencie istnieje więcej niż 10 wystąpień pliku wykonywalnego uruchomionego na komputerze.

Teraz, jeśli powyższe 3 biblioteki były bibliotekami współdzielonymi: Pierwsza Insance jest ładowana do pamięci RAM: Czas potrzebny do wykonania to czas pobierany przez main() foo.exe, aby załadować pamięć (przy założeniu, że jest pomijalny) + czas ładowania liba + czas ładowania Libb + czas ładowania libc Druga instancja jest uruchomiona: Załóżmy teraz, że uruchomiona jest druga instancja tego pliku wykonywalnego. Ponieważ wszystkie biblioteki są już załadowane do pamięci głównej, czas jest zajęty tylko dla załadowania głównej() do pamięci, która jest pomijalna.

Teraz, jeśli powyższe 3 biblioteki biblioteki tłoczenia: 1-te Insance jest ładowana do pamięci RAM: Czas potrzebny będzie czas potrzebny główne (I) foo.exe być ładowane pamięci (przy założeniu, że jego nieznaczny) + Czas do wczytaj liba + czas ładowania Libb + czas ładowania libc (Offcourse jest teraz całą częścią pliku wykonywalnego jako całości) Druga instancja jest uruchomiona: teraz załóżmy, że uruchomiona jest druga instancja tego pliku wykonywalnego. Pobrany czas to ponownie czas zajęty przez main() foo.exe do załadowania pamięci (przy założeniu, że jest pomijalny) + czas ładowania liba + time, aby załadować libb + czas, aby załadować libc. (Ponieważ każdy plik wykonywalny może współdzielić librareie, ponieważ są to statyczne biblioteki)

Podsumowując, w przypadku biblioteki statycznej czas ładowania będzie większy. Ale powiedziano mi, że współdzielone biblioteki zabierają więcej czasu podczas ładowania niż biblioteki statyczne, więc będzie opóźnienie, a więc biblioteki dzielone nie są dobrym rozwiązaniem. Jak to jest możliwe ?

Odpowiedz

9

Łączenie (rozwiązywanie referencji) nie jest bezpłatne. W przypadku łączenia statycznego rozdzielczość jest wykonywana raz na zawsze podczas generowania pliku binarnego. Dynamiczne łączenie musi być wykonywane za każdym razem, gdy ładowany jest plik binarny. Nie wspominając już o tym, że kod skompilowany do pracy w bibliotece współdzielonej może być mniej wydajny niż kod skompilowany do statycznego połączenia. Dokładny koszt zależy od architektury i implementacji dynamicznego łączenia systemu.

Koszt utworzenia dynamicznej biblioteki może być stosunkowo wysoki dla 32-bitowego zestawu instrukcji x86: w ELF binary format, jeden z już nielicznych rejestrów musi zostać poświęcony, aby dynamicznie połączony kod mógł zostać przeniesiony. Starszy format a.out umieszczał każdą wspólną bibliotekę w ustalonym miejscu, ale nie skalowano. Uważam, że Mac OS X miał system pośredni, gdy biblioteki dynamiczne były umieszczane we wcześniej ustalonych lokalizacjach w przestrzeni adresowej, ale konflikty rozwiązywano w skali pojedynczego komputera (długa faza "Optymalizacja wydajności systemu" po zainstalowaniu nowej oprogramowanie). W pewnym sensie ten system (nazwany pre-binding) pozwala ci mieć swoje ciasto i je zjeść. Nie wiem, czy wstępne bindowanie jest nadal konieczne teraz, gdy Apple prawie przeszedł na architekturę amd64.

Ponadto, na nowoczesnym systemie operacyjnym zarówno statycznie jak i dynamicznie połączony kod jest ładowany (przywoływany) z dysku, jeśli jest używany, ale jest to dość prostopadłe do twojego pytania.

+0

Bardzo dziękuję za tę niewiarygodnie szybką odpowiedź, mamy 2 scenariusze architektoniczne, podałem moje pytanie jako odpowiedź na moje pytanie, które znajduje się poniżej. – sud

2

Biblioteki statyczne są połączone w czasie kompilacji, biblioteki współdzielone są połączone w środowisku wykonawczym. Dlatego pliki wykonywalne korzystające z bibliotek statycznych amortyzują cały czas ich linku, zanim zostaną zapisane na dysku.

+0

Jeśli istnieją 3 biblioteki liba, libb, libc wszystkie są lib statyczne. Teraz dwa pliki wykonywalne foo1.exe i foo2.exe, które używają wszystkich 3 lib. 1. Jeśli uruchomionych zostanie wiele instancji foo1.exe, udostępnią one strony tekstowe. Czy to jest poprawne ? 2. Jeśli foo1.exe i foo2.exe są uruchomione w tym samym czasie, nie będą udostępniać stron tekstowych. Czy to jest poprawne ? Pls daj mi znać – sud

+0

W pierwszym przypadku udostępnione strony tekstowe będą miały postać foo1, a nie rzeczywistych bibliotek, ponieważ biblioteki już nie istnieją po statycznym łączeniu. W przeciwnym razie oba są poprawne. –

0

Bardzo dziękuję za tę niewiarygodnie szybką odpowiedź. mamy 2 scenariusze architektoniczne:

Q1.Architecure-1: Załóżmy exe o wielkości 3GB (biblioteki statyczne). 95% to biblioteki i 5% main(). Przy tak dużym rozmiarze ładowanie tego exe zajmie więcej czasu (przy założeniu statycznych bibliotek) lub połączenie tego exe zajmie więcej czasu (przy założeniu korzystania z bibliotek współdzielonych i jeśli wszystkie biblioteki są już w pamięci tylko linkowanie musi być zrobione.)

Architecure-2: Załóżmy, że mam rozmiar exe 1,5 GB (95% lib + 5% main()), a 6 wystąpień tego jest uruchomionych w tym samym czasie. Po tych 6 wystąpieniach będą działać przez kilka dni, zakładając, że jesteśmy gotowi do podjęcia dodatkowego opóźnienia podczas początkowego ładowania + łączenia tych 6 wystąpień.

Q2. Teraz, jeśli używam obiektów wspólnych zamiast obiektów statycznych, czy mam dużo wolnego miejsca w pamięci RAM, ponieważ wszystkie biblioteki są współużytkowane przez 6 instancji? czy przyspieszenie wykonywania w czasie rzeczywistym nie wzrośnie ze względu na więcej miejsca w pamięci RAM, co zmniejsza zamianę stron?

Q3. Jeśli użyję plików "map" w celu zmniejszenia liczby wyeksportowanych symboli (co jest możliwe tylko przy użyciu bibliotek współdzielonych), czy rozmiar mojej tablicy symboli nie spadnie i czy nie poprawi to wydajności środowiska wykonawczego?

Dzięki Sud

+0

Jeśli chodzi o uruchamianie wystąpień tego samego programu ("foo.exe" w oryginalnym pytaniu), kod zostanie udostępniony w pamięci (z wszystkimi zaletami) z statycznie połączoną wersją, tak samo jak z dynamicznie połączonym. –

+0

Tylko jeśli miałeś na myśli nieco inne programy foo1.exe, foo2.exe, każdy używający tego samego liba, libb, lic, miałby zalety dynamicznego linkowania. W tym przypadku tylko umożliwiłoby udostępnienie czegoś, czego nie można udostępnić statycznym łączom. –

+0

Właściwie zamierzałem powiedzieć, że ten sam plik wykonywalny foo.exe (przy użyciu statycznej biblioteki) ma 6 instancji zamiast foo1, foo2. Ale w takim przypadku w jaki sposób kod zostanie udostępniony w pamięci? Czy każda instancja nie ma własnej kopii w pamięci RAM? Myślałem, że tylko w bibliotekach współdzielonych będzie on udostępniany, a nie statyczną biblioteką. Czy możesz podać adres URL, który mógłby mnie oświecić. – sud

Powiązane problemy