Łączenie statyczne a dynamiczne

398

Czy istnieją jakieś istotne powody, dla których warto wybrać łączenie statyczne zamiast dynamicznego lub odwrotnie w niektórych sytuacjach? Słyszałem lub czytałem poniższe, ale nie wiem wystarczająco dużo na ten temat, by ręczyć za ich prawdziwość.

1) Różnica w wydajności środowiska wykonawczego między łączeniem statycznym a łączeniem dynamicznym jest zwykle nieistotna.

2) (1) nie jest prawdziwe, jeśli używasz kompilatora profilowania, który wykorzystuje dane profilu do optymalizacji ścieżek programu, ponieważ dzięki statycznemu łączeniu kompilator może zoptymalizować zarówno kod, jak i kod biblioteki. Dzięki dynamicznemu łączeniu tylko Twój kod może być zoptymalizowany. Jeśli spędza się większość czasu na uruchamianiu kodu biblioteki, może to mieć dużą różnicę. W przeciwnym razie (1) nadal obowiązuje.

Eloff
źródło
59
„Dzięki łączeniu statycznemu kompilator może zoptymalizować kod biblioteki”, ale tylko wtedy, gdy to skompiluje! Jeśli po prostu umieścisz linki do wstępnie skompilowanych plików obiektowych, Twój kompilator nie będzie miał okazji ich zoptymalizować.
3
Jeśli to prawda, masz rację, ale jest pewne pytanie, jak prawdziwe jest to w przypadku nowoczesnych kompilatorów, czy ktoś może to sprawdzić w ten czy inny sposób, byłoby świetnie.
Eloff,
5
Dzięki kompilatorowi kompilującemu się do kodu natywnego (jak większość kompilatorów C / C ++) nie ma już żadnej szansy na optymalizację kodu. Jeśli kod zostanie skompilowany do jakiegoś języka pośredniego (takiego jak .Net IL), kompilator JIT zostanie wywołany podczas ładowania biblioteki, aby skompilować go do kodu natywnego. Ta ostateczna kompilacja może z czasem stać się coraz lepsza wraz z rozwojem kompilatora JIT.
Tarydon
3
@Eloff: VS2008 robi dokładnie to z włączonym LTCG. (Pliki lib stają się jednak ogromne…) Bawiłem się nimi i dla kogoś, kto jest zainteresowany tym, co mój kompilator może dla mnie zrobić, to nic nadzwyczajnego.
peterchen

Odpowiedzi:

347
  • Łączenie dynamiczne może zmniejszyć całkowite zużycie zasobów (jeśli więcej niż jeden proces korzysta z tej samej biblioteki (w tym oczywiście wersja w „tym samym”). Uważam, że jest to argument, który napędza jego obecność w większości środowisk. Tutaj „zasoby” obejmują miejsce na dysku, pamięć RAM i pamięć podręczną. Oczywiście, jeśli twój dynamiczny linker nie jest wystarczająco elastyczny, istnieje ryzyko piekła DLL .
  • Dynamiczne powiązanie oznacza, że poprawki i uaktualnienia do bibliotek propagować poprawić swój produkt bez konieczności wysyłać cokolwiek.
  • Wtyczki zawsze wymagają dynamicznego linkowania.
  • Łączenie statyczne oznacza, że ​​możesz wiedzieć, że kod będzie działał w bardzo ograniczonych środowiskach (na początku procesu rozruchu lub w trybie ratunkowym).
  • Łączenie statyczne może ułatwić dystrybucję plików binarnych do różnych środowisk użytkowników (kosztem wysłania większego i bardziej wymagającego zasobów programu).
  • Łączenie statyczne może pozwolić na nieco krótsze czasy uruchamiania , ale zależy to w pewnym stopniu zarówno od wielkości i złożoności programu, jak i od szczegółów strategii ładowania systemu operacyjnego.

Niektóre zmiany zawierają bardzo trafne sugestie w komentarzach i innych odpowiedziach. Chciałbym zauważyć, że sposób, w jaki się na to włamujesz, zależy w dużej mierze od środowiska, w którym zamierzasz działać. Minimalne systemy wbudowane mogą nie mieć wystarczających zasobów do obsługi dynamicznego łączenia. Nieco większe małe systemy mogą obsługiwać dynamiczne łączenie, ponieważ ich pamięć jest na tyle mała, że ​​oszczędność pamięci RAM z dynamicznego łączenia jest bardzo atrakcyjna. W pełni rozwinięte komputery konsumenckie mają, jak zauważa Mark, ogromne zasoby, i prawdopodobnie możesz pozwolić, aby problemy z wygodą wpłynęły na twoje myślenie w tej sprawie.


Aby rozwiązać problemy z wydajnością i wydajnością: to zależy .

Klasycznie biblioteki dynamiczne wymagają pewnego rodzaju warstwy kleju, co często oznacza podwójne wysyłanie lub dodatkową warstwę pośredniczącą w adresowaniu funkcji i może kosztować trochę prędkości (ale czy czas wywoływania funkcji jest rzeczywiście dużą częścią twojego czasu działania ???).

Jeśli jednak uruchomisz wiele procesów, z których wszystkie często wywołują tę samą bibliotekę, możesz w końcu zapisać linie pamięci podręcznej (a tym samym zyskać na wydajności), używając dynamicznego linkowania w porównaniu do statycznego linkowania. (Chyba że współczesne systemy operacyjne są wystarczająco inteligentne, aby zauważyć identyczne segmenty w statycznie połączonych plikach binarnych. Wydaje się trudne, ktoś wie?)

Kolejny problem: czas ładowania. W pewnym momencie ponosisz koszty załadunku. Kiedy płacisz, ten koszt zależy od tego, jak działa system operacyjny, a także od tego, z jakiego łącza korzystasz. Może wolisz odłożyć płacenie, dopóki nie będziesz wiedział, że go potrzebujesz.

Zauważ, że łączenie statyczne z dynamicznym tradycyjnie nie jest problemem optymalizacji, ponieważ oba wymagają osobnej kompilacji w dół do plików obiektowych. Nie jest to jednak wymagane: kompilator może co do zasady „kompilować” „biblioteki statyczne” do przetworzonego formularza AST i „łączyć” je, dodając te AST do generowanych dla głównego kodu, zapewniając w ten sposób globalną optymalizację. Żaden z używanych przeze mnie systemów tego nie robi, więc nie mogę komentować, jak dobrze działa.

Odpowiedzią na pytania dotyczące wydajności jest zawsze testowanie (i używanie środowiska testowego tak bardzo, jak to możliwe).

dmckee --- były kot moderator
źródło
24
Zużycie zasobów to w zasadzie przestrzeń kodu, która z czasem staje się coraz mniej istotna. Jeśli 500 000 bibliotek jest współużytkowanych przez 5 procesów, oznacza to 2 MB oszczędności, co stanowi mniej niż 0,1% z 3 GB pamięci RAM.
Mark Ransom
3
Jeśli biblioteka współdzieli również to samo odwzorowanie wirtualne (ten sam adres fizyczny i wirtualny we wszystkich procesach), czy dynamiczne łącze nie zapisuje również miejsc TLB w MMU procesora?
Zan Lynx
6
Również link dynamiczny ułatwia aktualizację błędnego kodu biblioteki za pomocą lepszych wersji.
Zan Lynx
89
@Zan Ułatwia także dodawanie błędnego kodu do działającej wersji.
6
„Wtyczki zawsze wymagają dynamicznego linkowania”. To jest niepoprawne Niektóre modele wtyczek, takie jak AudioUnits firmy Apple, mogą uruchamiać wtyczkę w osobnym procesie i korzystać z IPC. Jest to bezpieczniejsza alternatywa dla dynamicznego linkowania wtyczek (wtyczka nie może zawiesić hosta). Zaproponuj aktualizację odpowiedzi na „Wtyczki mogą wymagać dynamicznego linkowania” lub podobnego.
Taylor
68

1) polega na tym, że wywołanie funkcji DLL zawsze wykorzystuje dodatkowy skok pośredni. Dzisiaj jest to zwykle nieistotne. Wewnątrz biblioteki DLL występuje więcej obciążenia na procesorach i386, ponieważ nie mogą one generować kodu niezależnego od pozycji. Na amd64 skoki mogą być względne względem licznika programu, więc jest to ogromna poprawa.

2) To prawda. Dzięki optymalizacjom prowadzonym przez profilowanie zwykle można uzyskać około 10-15 procent wydajności. Teraz, gdy szybkość procesora osiągnęła już limit, warto to zrobić.

Dodałbym: (3) linker może organizować funkcje w bardziej wydajnym grupowaniu pamięci podręcznej, aby zminimalizować kosztowne pomyłki w poziomie pamięci podręcznej. Może to również w szczególności wpłynąć na czas uruchamiania aplikacji (na podstawie wyników, które widziałem z kompilatorem Sun C ++)

I nie zapominaj, że w bibliotekach DLL nie można wyeliminować martwego kodu. W zależności od języka kod DLL może również nie być optymalny. Funkcje wirtualne są zawsze wirtualne, ponieważ kompilator nie wie, czy klient go nadpisuje.

Z tych powodów, na wypadek, gdyby nie było potrzeby używania bibliotek DLL, wystarczy użyć kompilacji statycznej.

EDYCJA (aby odpowiedzieć na komentarz, podkreślenie użytkownika)

Oto dobry zasób na temat problemu z kodem niezależnym od pozycji http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/

Jak wyjaśniono, x86 nie ma ich AFAIK dla niczego innego niż 15-bitowe zakresy skoków, a nie dla bezwarunkowych skoków i wywołań. Dlatego funkcje (z generatorów) mające ponad 32 KB zawsze stanowiły problem i wymagały wbudowanych trampolin.

Ale w popularnym systemie operacyjnym x86, takim jak Linux, nie trzeba się przejmować, jeśli plik .so / DLL nie zostanie wygenerowany za pomocą gccprzełącznika -fpic(co wymusza użycie pośrednich tabel skoków). Ponieważ jeśli tego nie zrobisz, kod zostanie naprawiony tak, jak zwykły linker go przeniesie. Ale czyniąc to, segment kodu nie jest współdzielony i potrzebowałoby pełnego odwzorowania kodu z dysku do pamięci i dotknięcia go, zanim będzie można go użyć (opróżnienie większości pamięci podręcznych, uderzenie w TLB) itp. Był czas kiedy uznano to za wolne.

Więc nie miałbyś już żadnych korzyści.

Nie przypominam sobie, co dało OS (Solaris czy FreeBSD) mi problemy z moim systemie build Unix, bo po prostu nie było to robi i zastanawiał się, dlaczego rozbił aż stosowane -fPICdo gcc.

Lothar
źródło
4
Podoba mi się ta odpowiedź, ponieważ jako jedyna odnosiła się do kwestii poruszonych w pytaniu.
Eloff,
Interesujące byłoby posiadanie odniesień do tych specyfikacji DLL i porównanie różnych systemów operacyjnych.
UncleZeiv 16.04.10
Niby dobrze, ale szybkość procesora zdecydowanie nie osiągnęła swoich granic.
Aidiakapi
67

Dynamiczne łączenie jest jedynym praktycznym sposobem spełnienia niektórych wymagań licencyjnych, takich jak LGPL .

Mark Ransom
źródło
17
Tak długo, jak użytkownik końcowy może połączyć się ponownie z kodem LGPL (np. Ponieważ udostępniasz kod źródłowy lub skompilowane pliki obiektowe wraz z oprogramowaniem), łączenie statyczne jest w porządku . Dodatkowo, jeśli twoje oprogramowanie jest do użytku wewnętrznego (tj. Do użytku tylko w twojej organizacji, a nie rozpowszechniane), możesz połączyć statycznie. Dotyczy to np. Oprogramowania serwera, w którym serwer nie jest rozpowszechniany.
JBentley,
3
Nie rozumiem Czy możesz podać mi więcej źródeł (lub rozwinąć więcej), aby docenić to, co napisałeś?
Baskaya,
4
@Thorn patrz sekcja licencji LGPL 4.d + e . Musisz albo rozpowszechniać w formie, która wymaga od użytkownika wykonania łącza, albo rozpowszechniać udostępnioną (dynamiczną) bibliotekę.
Mark Ransom,
46

Zgadzam się z punktami wspomnianymi przez dnmckee oraz:

  • Aplikacje połączone statycznie mogą być łatwiejsze do wdrożenia, ponieważ istnieje mniej lub nie ma żadnych dodatkowych zależności plików (.dll / .so), które mogą powodować problemy, gdy zostaną zagubione lub zainstalowane w niewłaściwym miejscu.
stakx - już nie przyczynia się
źródło
6
Warto zauważyć, że kompilator Go od Google będzie tylko statycznie kompilował pliki binarne głównie z tego powodu.
Hut8
34

Jednym z powodów wykonania kompilacji statycznie powiązanej jest sprawdzenie, czy masz pełne zamknięcie pliku wykonywalnego, tj. Czy wszystkie odwołania do symboli zostały poprawnie rozwiązane.

W ramach dużego systemu, który był budowany i testowany przy użyciu ciągłej integracji, nocne testy regresji były przeprowadzane przy użyciu statycznie powiązanej wersji plików wykonywalnych. Czasami widzieliśmy, że symbol się nie rozwiąże, a łącze statyczne ulegnie awarii, nawet jeśli dynamicznie połączony plik wykonywalny zostanie pomyślnie połączony.

Miało to zwykle miejsce, gdy symbole, które były głęboko osadzone w udostępnionych bibliotekach, miały błędnie napisaną nazwę i dlatego nie łączyły się statycznie. Dynamiczny linker nie rozpoznaje w pełni wszystkich symboli, bez względu na to, czy zastosowano ocenę głębokości, czy szerokość, więc możesz zakończyć z dynamicznie połączonym plikiem wykonywalnym, który nie ma pełnego zamknięcia.

Rob Wells
źródło
1
bardzo dobra uwaga, próbowałem to ostatnio zrobić z jakimś kodem, który mam w pracy, ale kompilowanie wszystkiego statycznie okazało się zaskakująco denerwujące i właśnie się poddałem
UncleZeiv
21

1 / Brałem udział w projektach, w których porównano dynamiczne łączenie z łączeniem statycznym, a różnica nie była wystarczająco mała, aby przejść na łączenie dynamiczne (nie brałem udziału w teście, po prostu znam wniosek)

2 / Dynamiczne łączenie jest często powiązane z PIC (kod niezależny od pozycji, kod, który nie musi być modyfikowany w zależności od adresu, pod którym jest ładowany). W zależności od architektury PIC może przynieść kolejne spowolnienie, ale jest potrzebne w celu uzyskania korzyści z dzielenia się dynamicznie połączoną biblioteką między dwoma plikami wykonywalnymi (a nawet dwoma procesami tego samego pliku wykonywalnego, jeśli system operacyjny używa losowego adresu obciążenia jako środka bezpieczeństwa). Nie jestem pewien, czy wszystkie systemy operacyjne pozwalają rozdzielić te dwie koncepcje, ale Solaris i Linux to robią, a ISTR tak samo jak HP-UX.

3 / Brałem udział w innych projektach, które korzystały z dynamicznego linkowania dla funkcji „łatwej łatki”. Ale ta „łatwa łatka” sprawia, że ​​dystrybucja małej poprawki jest nieco łatwiejsza, a skomplikowanej koszmarem wersjonowania. Często kończyliśmy się tym, że musieliśmy wszystko przepychać, a także musieliśmy śledzić problemy w witrynie klienta, ponieważ niewłaściwa wersja była tokenem.

Mój wniosek jest taki, że użyłem linkowania statycznego, z wyjątkiem:

  • dla rzeczy takich jak wtyczki, które zależą od dynamicznego linkowania

  • gdy współużytkowanie jest ważne (duże biblioteki używane przez wiele procesów jednocześnie, takie jak środowisko wykonawcze C / C ++, biblioteki GUI, ... które często są zarządzane niezależnie i dla których ABI jest ściśle określone)

Jeśli ktoś chce skorzystać z „łatwej łatki”, argumentowałbym, że bibliotekami należy zarządzać tak, jak duże biblioteki powyżej: muszą one być prawie niezależne z określonym ABI, którego nie można zmieniać za pomocą poprawek.

AProgrammer
źródło
1
Niektóre systemy operacyjne dla procesorów innych niż PIC lub drogich PIC przygotują biblioteki dynamiczne do załadowania pod konkretny adres w pamięci, a jeśli to zrobią, po prostu mapują kopię biblioteki na każdy proces, który się z nią łączy. To znacznie zmniejsza obciążenie PIC. Robią to przynajmniej OS X i niektóre dystrybucje Linuksa, nie jestem pewien co do systemu Windows.
Andrew McGregor
Dzięki Andrew, nie wiedziałem, że niektóre dystrybucje Linuksa tego używają. Czy masz referencję, którą mogę śledzić, lub słowo kluczowe, które mogę wyszukać, aby dowiedzieć się więcej? (FWIW Słyszałem, że Windows robi taką odmianę, ale Windows jest zbyt daleko poza moją strefą kompetencji, żebym o tym wspominał).
AProgrammer
Myślę, że szukanym słowem kluczowym jest „prelink” - przygotowuje bibliotekę do szybkiego załadowania pod określonym adresem, aby przyspieszyć uruchamianie programu.
Blaisorblade,
20

Ten omówić szczegółowo o współdzielonych bibliotek implikacji Linux i wydajności.

nos
źródło
3
+1 za linkowanie do instrukcji DSO Dreppera, którą każdy, kto tworzy biblioteki w Linuksie, powinien przeczytać.
janneb
10

W systemach uniksowych dynamiczne łączenie może utrudnić „rootowi” korzystanie z aplikacji z bibliotekami współdzielonymi zainstalowanymi w nietypowych lokalizacjach. Wynika to z faktu, że dynamiczny linker zasadniczo nie zwraca uwagi na LD_LIBRARY_PATH lub jego odpowiednik dla procesów z uprawnieniami roota. Czasami więc statyczne łączenie ratuje dzień.

Alternatywnie proces instalacji musi zlokalizować biblioteki, ale może to utrudnić współistnienie wielu wersji oprogramowania na komputerze.

Jonathan Leffler
źródło
1
Chodzi o LD_LIBRARY_PATHto, że nie jest dokładnie przeszkodą w korzystaniu z bibliotek współdzielonych, przynajmniej nie w GNU / Linux. Np. Jeśli umieścisz współdzielone biblioteki w katalogu ../lib/względem pliku programu, to w łańcuchu narzędzi GNU opcja linkera -rpath $ORIGIN/../libokreśli przeszukiwanie biblioteki z tej względnej lokalizacji. Następnie możesz łatwo przenieść aplikację wraz ze wszystkimi powiązanymi bibliotekami współdzielonymi. Dzięki tej sztuczce nie ma problemu z posiadaniem wielu wersji aplikacji i bibliotek (zakładając, że są one powiązane, jeśli nie, możesz użyć dowiązań symbolicznych).
FooF,
> dla procesów z uprawnieniami roota. Myślę, że mówisz o programach setuid uruchamianych przez użytkowników innych niż root - w przeciwnym razie nie ma to sensu. A binarny plik setuid z bibliotekami w niestandardowych lokalizacjach jest dziwny - ale ponieważ tylko root może zainstalować te programy, może również edytować /etc/ld.so.confw tym przypadku.
Blaisorblade,
10

To naprawdę bardzo proste. Kiedy wprowadzasz zmiany w kodzie źródłowym, czy chcesz poczekać 10 minut na kompilację, czy 20 sekund? Dwadzieścia sekund to wszystko, co mogę znieść. Poza tym albo wyjmuję miecz, albo zaczynam myśleć o tym, jak mogę użyć osobnej kompilacji i linków, aby przywrócić go do strefy komfortu.

Hans Passant
źródło
1
Tak naprawdę nie porównałem różnicy prędkości kompilacji, ale dynamicznie linkowałbym, gdyby był znacznie szybszy. Boost robi tyle złych rzeczy w moich czasach kompilacji.
Eloff,
9

Najlepszym przykładem dynamicznego łączenia jest sytuacja, gdy biblioteka zależy od używanego sprzętu. W czasach starożytnych biblioteka matematyki C była dynamiczna, aby każda platforma mogła wykorzystać wszystkie możliwości procesora do jej optymalizacji.

Jeszcze lepszym przykładem może być OpenGL. OpenGl to interfejs API, który jest różnie implementowany przez AMD i NVidia. Nie możesz użyć implementacji NVidia na karcie AMD, ponieważ sprzęt jest inny. Z tego powodu nie można połączyć statycznie OpenGL ze swoim programem. Stosowane jest tutaj dynamiczne łączenie, aby umożliwić optymalizację interfejsu API dla wszystkich platform.

Arne
źródło
8

Łączenie dynamiczne wymaga dodatkowego czasu, aby system operacyjny znalazł bibliotekę dynamiczną i załadował ją. Dzięki łączeniu statycznemu wszystko jest razem i jest to jednorazowe ładowanie do pamięci.

Zobacz także DLL Hell . W tym scenariuszu biblioteka DLL ładowana przez system operacyjny nie jest biblioteką dostarczoną z aplikacją ani wersją oczekiwaną przez aplikację.

Thomas Matthews
źródło
1
Ważne jest, aby pamiętać, że istnieje szereg środków zaradczych, aby uniknąć DLL Hell.
ocodo
5

Innym zagadnieniem, które nie zostało jeszcze omówione, jest usuwanie błędów w bibliotece.

Dzięki statycznemu łączeniu nie tylko musisz odbudować bibliotekę, ale także będzie musiał ponownie połączyć i rozpowszechnić plik wykonywalny. Jeśli biblioteka jest używana tylko w jednym pliku wykonywalnym, może to nie stanowić problemu. Ale im więcej plików wykonywalnych wymaga ponownego połączenia i redystrybucji, tym większy jest ból.

Dzięki dynamicznemu łączeniu po prostu odbudowujesz i redystrybuujesz bibliotekę dynamiczną i gotowe.

R Samuel Klatchko
źródło
2

linkowanie statyczne daje tylko jeden plik exe, w celu dokonania zmiany potrzebnej do ponownej kompilacji całego programu. Podczas gdy w dynamicznym łączeniu musisz wprowadzać zmiany tylko w bibliotece dll, a kiedy uruchomisz exe, zmiany będą pobierane w czasie wykonywania. Łatwiej jest dostarczać aktualizacje i poprawki błędów przez dynamiczne łączenie (np. Windows).

Govardhan Murali
źródło
2

Istnieje ogromna i rosnąca liczba systemów, w których ekstremalny poziom statycznego łączenia może mieć ogromny pozytywny wpływ na aplikacje i wydajność systemu.

Mam na myśli tak zwane „systemy wbudowane”, z których wiele coraz częściej korzysta z systemów operacyjnych ogólnego zastosowania, a systemy te są wykorzystywane do wszystkiego, co można sobie wyobrazić.

Niezwykle częstym przykładem są urządzenia korzystające z systemów GNU / Linux korzystających z Busybox . Doszedłem do skrajności w NetBSD , budując bootowalny obraz systemu i386 (32-bitowy), który zawiera zarówno jądro, jak i jego główny system plików, ten ostatni, który zawiera pojedynczy crunchgenplik binarny połączony statycznie z twardymi dowiązaniami do wszystkie programy, które same zawierają wszystkie (w końcu 274) standardowych pełnowartościowych programów systemowych (większość z wyjątkiem łańcucha narzędzi), i mają mniej niż 20 megabajtów (i prawdopodobnie działają bardzo wygodnie w systemie z zaledwie 64 MB pamięci (nawet przy głównym systemie plików nieskompresowanym i całkowicie w pamięci RAM), chociaż nie byłem w stanie znaleźć takiego tak małego do przetestowania).

We wcześniejszych postach wspomniano, że czas uruchamiania plików binarnych połączonych statycznie jest krótszy (i może być znacznie szybszy), ale jest to tylko część obrazu, zwłaszcza gdy cały kod obiektu jest połączony w tym samym , a zwłaszcza, gdy system operacyjny obsługuje stronicowanie na żądanie kodu bezpośrednio z pliku wykonywalnego. W tym idealnym scenariuszu czas uruchamiania programów jest dosłownie nieistotny, ponieważ prawie wszystkie strony kodu będą już w pamięci i będą używane przez powłokę (i initwszelkie inne działające procesy w tle), nawet jeśli żądany program nie był uruchamiany od czasu rozruchu, ponieważ być może wystarczy załadować tylko jedną stronę pamięci, aby spełnić wymagania programu dotyczące czasu wykonywania.

Jednak to jeszcze nie koniec. Zazwyczaj buduję i używam instalacji systemu operacyjnego NetBSD dla moich pełnych systemów programistycznych, łącząc statycznie wszystkie pliki binarne. Mimo że zajmuje to znacznie więcej miejsca na dysku (łącznie ~ 6,6 GB dla x86_64 ze wszystkim, w tym toolchain i X11 z linkami statycznymi) (zwłaszcza jeśli jedna pełna tablica symboli debugowania jest dostępna dla wszystkich innych programów ~ 2,5 GB), wynik nadal działa ogólnie szybciej, a dla niektórych zadań zużywa nawet mniej pamięci niż typowy system z dynamicznym łączem, który służy do udostępniania stron kodowych biblioteki. Dysk jest tani (nawet szybki), a pamięć do buforowania często używanych plików dyskowych jest również stosunkowo tania, ale cykle procesora tak naprawdę nie są, i ponoszenie ld.sokosztów uruchomienia za każdy proces, który rozpoczyna się coczas, w którym się uruchomi, zajmie wiele godzin cykli procesora od zadań wymagających uruchomienia wielu procesów, szczególnie gdy te same programy są używane w kółko, takie jak kompilatory w systemie programistycznym. Statycznie połączone programy narzędziowe mogą skracać czas kompilacji wielu architektur całego systemu operacyjnego o kilka godzin . Muszę jeszcze wbudować łańcuch narzędzi w mój pojedynczy crunchgenplik binarny, ale podejrzewam, że kiedy to zrobię, zaoszczędzę więcej czasu na kompilacji z powodu wygranej w pamięci podręcznej procesora.

Greg A. Woods
źródło
2

Łączenie statyczne obejmuje pliki potrzebne programowi w jednym pliku wykonywalnym.

Dynamiczne łączenie jest tym, co można by uznać za zwykłe, powoduje, że plik wykonywalny, który nadal wymaga bibliotek DLL i znajduje się w tym samym katalogu (lub biblioteki DLL mogą znajdować się w folderze systemowym).

(DLL = biblioteka linków dynamicznych )

Dynamicznie połączone pliki wykonywalne są kompilowane szybciej i nie wymagają tak dużych zasobów.

Nykal
źródło
0

Static linking jest procesem w czasie kompilacji, gdy połączona treść jest kopiowana do podstawowego pliku binarnego i staje się pojedynczym plikiem binarnym.

Cons:

  • czas kompilacji jest dłuższy
  • wyjściowy plik binarny jest większy

Dynamic linkingto proces w czasie wykonywania, gdy ładowana jest połączona zawartość. Ta technika pozwala:

  • uaktualnij połączony plik binarny bez ponownej kompilacji podstawowego, który zwiększa ABIstabilność [Informacje]
  • mieć jedną udostępnioną kopię

Cons:

  • czas rozpoczęcia jest dłuższy (powiązane treści należy skopiować)
  • błędy łącznika są zgłaszane w czasie wykonywania
yoAlex5
źródło