स्टेटिक लिंकिंग बनाम डायनेमिक लिंकिंग


398

क्या डायनेमिक लिंकिंग पर स्थिर लिंकिंग चुनने के लिए कोई आकर्षक प्रदर्शन कारण हैं या कुछ स्थितियों में इसके विपरीत? मैंने निम्नलिखित को सुना या पढ़ा है, लेकिन मैं इस विषय पर पर्याप्त नहीं जानता कि इसकी सत्यता के लिए क्या करना है।

1) स्टेटिक लिंकिंग और डायनेमिक लिंकिंग के बीच रनटाइम परफॉर्मेंस में अंतर आमतौर पर नगण्य होता है।

2) (1) सही नहीं है यदि प्रोफाइलिंग कंपाइलर का उपयोग किया जाता है जो प्रोग्राम हॉटपैथ को अनुकूलित करने के लिए प्रोफाइल डेटा का उपयोग करता है क्योंकि स्टेटिक लिंकिंग के साथ, कंपाइलर आपके कोड और लाइब्रेरी कोड दोनों को ऑप्टिमाइज़ कर सकता है। डायनामिक लिंकिंग के साथ केवल आपके कोड को ऑप्टिमाइज़ किया जा सकता है। यदि अधिकांश समय लाइब्रेरी कोड चलाने में बीतता है, तो यह एक बड़ा बदलाव ला सकता है। अन्यथा, (1) अभी भी लागू होता है।


59
"स्टैटिक लिंकिंग के साथ, कंपाइलर ऑप्टिमाइज़ कर सकता है .. लाइब्रेरी कोड" लेकिन केवल अगर यह भी कंपाइल करता है! यदि आप केवल पूर्व-संकलित ऑब्जेक्ट फ़ाइलों से लिंक करते हैं, तो आपके कंपाइलर को उन्हें अनुकूलित करने का मौका नहीं मिलता है।

3
यदि यह सच है, तो आप सही हैं, लेकिन कुछ प्रश्न हैं कि आधुनिक संकलक के साथ कितना सही है, अगर कोई इसे एक या दूसरे तरीके से सत्यापित कर सकता है, तो यह बहुत अच्छा होगा।
एलॉफ

5
मूल कोड के संकलनकर्ता के साथ (जैसे अधिकांश C / C ++ कंपाइलर) कोड अनुकूलन के लिए आगे कोई मौका नहीं है। यदि कोड को कुछ मध्यवर्ती भाषा (जैसे .Net IL) में संकलित किया जाता है, तो JIT संकलक तब आह्वान किया जाता है, जब पुस्तकालय इसे मूल कोड में संकलित करने के लिए लोड हो रहा होता है। जेआईटी संकलक विकसित होने के साथ ही अंतिम संकलन समय के साथ बेहतर हो सकता है।
टैरिडन

3
@Eloff: VS2008 एलटीसीजी सक्षम के साथ ठीक वैसा ही करता है। (Lib फ़ाइलें बहुत बड़ी हो जाती हैं, हालांकि ..) मैंने इसके साथ खिलवाड़ किया है और "मेरी कंपाइलर मेरे लिए क्या कर सकती है" में रुचि रखने वाले किसी व्यक्ति के लिए, यह आश्चर्यजनक से कम नहीं है।
पेट्रीचेन

जवाबों:


347
  • डायनेमिक लिंकिंग कुल संसाधन खपत को कम कर सकती है (यदि एक से अधिक प्रक्रिया समान लाइब्रेरी साझा करती है (संस्करण में "समान", निश्चित रूप से सहित))। मेरा मानना ​​है कि यह तर्क है जो इसे अधिकांश वातावरणों में अपनी उपस्थिति को संचालित करता है। यहां "संसाधनों" में डिस्क स्थान, रैम और कैश स्थान शामिल हैं। बेशक, अगर आपका डायनेमिक लिंकर अपर्याप्त रूप से लचीला है तो DLL नरक का खतरा है
  • डायनेमिक लिंकिंग का अर्थ है कि बग फिक्स और लाइब्रेरी में अपग्रेड करना आपके उत्पाद को बेहतर बनाने के लिए आपको कुछ भी जहाज करने की आवश्यकता के बिना प्रचारित करता है।
  • प्लगइन्स हमेशा गतिशील के लिए कहते हैं लिंकिंग के ।
  • स्टेटिक लिंकिंग, का अर्थ है कि आप जान सकते हैं कि कोड बहुत सीमित वातावरण में चलेगा (बूट प्रक्रिया में, या बचाव मोड में)।
  • स्टेटिक लिंकिंग से बायनेरिज़ को वितरित करना आसान हो सकता है को विविध उपयोगकर्ता वातावरणों में करने के है (बड़े और अधिक संसाधन भूख कार्यक्रम भेजने की लागत पर)।
  • स्टेटिक जोड़ने थोड़ा अनुमति दे सकता है तेजी से स्टार्टअप बार, लेकिन यह दोनों आकार और अपने कार्यक्रम की जटिलता पर कुछ हद तक निर्भर करता है और ओएस लोड हो रहा है रणनीति के विवरण पर।

कुछ संपादन टिप्पणियों में और अन्य उत्तरों में बहुत प्रासंगिक सुझावों को शामिल करने के लिए। मैं यह नोट करना चाहता हूं कि जिस तरह से आप इस पर टूटते हैं, वह इस बात पर बहुत कुछ निर्भर करता है कि आप किस वातावरण में चलाने की योजना बना रहे हैं। न्यूनतम एम्बेडेड सिस्टम में गतिशील लिंकिंग का समर्थन करने के लिए पर्याप्त संसाधन नहीं हो सकते हैं। थोड़ा बड़ा छोटे सिस्टम अच्छी तरह से डायनेमिक लिंकिंग का समर्थन कर सकते हैं, क्योंकि रैम की बचत डायनामिक लिंकिंग से रैम को बहुत आकर्षक बनाने के लिए पर्याप्त है। पूर्ण विकसित उपभोक्ता पीसी में मार्क नोट, विशाल संसाधन होते हैं, और आप शायद इस मुद्दे पर सुविधा मुद्दों को अपनी सोच को चलाने दे सकते हैं।


प्रदर्शन और दक्षता के मुद्दों को संबोधित करने के लिए: यह निर्भर करता है

शास्त्रीय रूप से, गतिशील पुस्तकालयों को कुछ प्रकार की गोंद परत की आवश्यकता होती है, जिसका अर्थ अक्सर डबल डिस्पैच होता है या फ़ंक्शन एड्रेसिंग में अप्रत्यक्ष की एक अतिरिक्त परत होती है और इसमें थोड़ी गति खर्च हो सकती है (लेकिन फ़ंक्शन कॉलिंग समय वास्तव में आपके चलने के समय का एक बड़ा हिस्सा है ???)।

हालाँकि, यदि आप एक से अधिक प्रक्रियाएँ चला रहे हैं, जो सभी एक ही लाइब्रेरी को बहुत कहते हैं, तो आप स्थैतिक लिंकिंग का उपयोग करते हुए डायनेमिक लिंकिंग का उपयोग करते हुए कैश लाइन्स (और इस प्रकार रनिंग पर जीत हासिल कर सकते हैं) को समाप्त कर सकते हैं। (जब तक कि आधुनिक OS स्मार्ट रूप से जुड़े बायनेरिज़ में समान सेगमेंट को नोटिस करने के लिए पर्याप्त स्मार्ट नहीं है। कठिन लगता है, किसी को पता है?)

एक और मुद्दा: लोडिंग समय। आप कुछ बिंदु पर लोडिंग लागत का भुगतान करते हैं। जब आप इस लागत का भुगतान करते हैं तो यह निर्भर करता है कि ओएस कैसे काम करता है और साथ ही साथ आप किस लिंक का उपयोग करते हैं। हो सकता है कि आप इसे तब तक देना बंद कर दें जब तक आपको पता न हो कि आपको इसकी आवश्यकता है।

ध्यान दें कि स्थिर-बनाम-गतिशील जोड़ने पारंपरिक रूप से है नहीं , एक अनुकूलन मुद्दा है क्योंकि वे दोनों वस्तु फ़ाइलों के लिए नीचे अलग संकलन शामिल है। हालांकि, यह आवश्यक नहीं है: एक संकलक सिद्धांत रूप में, एक पचा हुआ एएसटी रूप में "स्टैटिक लाइब्रेरी" संकलित कर सकता है, और मुख्य कोड के लिए उत्पन्न लोगों के लिए उन एएसटी को जोड़कर उन्हें "लिंक" कर सकता है, इस प्रकार वैश्विक अनुकूलन को सशक्त बनाता है। मेरे द्वारा उपयोग की जाने वाली कोई भी प्रणाली ऐसा नहीं करती है, इसलिए मैं इस पर टिप्पणी नहीं कर सकता कि यह कितनी अच्छी तरह काम करता है।

प्रदर्शन के सवालों का जवाब देने का तरीका हमेशा परीक्षण द्वारा होता है (और परीक्षण वातावरण का यथासंभव उपयोग करें)


24
संसाधन की खपत मूल रूप से कोड स्पेस है, जो समय बीतने के साथ कम होती है और चिंता कम होती है। यदि 500K लाइब्रेरी को 5 प्रक्रियाओं के बीच साझा किया जाता है जो 2MB बचत है, जो 3GB RAM के .1% से कम है।
मार्क रैनसम

3
यदि लाइब्रेरी समान वर्चुअल मैपिंग (सभी प्रक्रियाओं में समान भौतिक और वर्चुअल पता) साझा करती है, तो क्या डायनेमिक लिंक भी प्रोसेसर के MMU में TLB स्लॉट्स को नहीं बचाता है?
ज़ैन लिंक्स

6
इसके अलावा एक गतिशील लिंक बेहतर संस्करणों के साथ छोटी गाड़ी लाइब्रेरी कोड को अपडेट करना आसान बनाता है।
ज़ैन लिंक्स

89
@Zan यह एक काम करने वाले संस्करण में छोटी गाड़ी कोड को जोड़ना भी आसान बनाता है।

6
"प्लगइन्स हमेशा गतिशील लिंकिंग के लिए कॉल करते हैं।" यह गलत है। कुछ प्लगइन मॉडल जैसे कि Apple के AudioUnits एक अलग प्रक्रिया में प्लगइन चला सकते हैं और IPC का उपयोग कर सकते हैं। यह प्लगइन्स के लिए डायनेमिक लिंकिंग का एक सुरक्षित विकल्प है (प्लगइन होस्ट को क्रैश नहीं कर सकता है)। उत्तर का सुझाव "प्लगइन्स को गतिशील लिंकिंग की आवश्यकता हो सकती है" या इसी तरह अद्यतन किया जाए।
टेलर

68

1) इस तथ्य पर आधारित है कि DLL फ़ंक्शन को कॉल करना हमेशा एक अतिरिक्त अप्रत्यक्ष कूद का उपयोग करता है। आज, यह आमतौर पर नगण्य है। DL3 के अंदर i386 सीपीयू पर कुछ और ओवरहेड है, क्योंकि वे स्थिति स्वतंत्र कोड उत्पन्न नहीं कर सकते हैं। Amd64 पर, कूदता प्रोग्राम काउंटर के सापेक्ष हो सकता है, इसलिए यह एक बहुत बड़ा सुधार है।

2) यह सही है। प्रोफाइलिंग द्वारा निर्देशित अनुकूलन के साथ आप आमतौर पर लगभग 10-15 प्रतिशत प्रदर्शन जीत सकते हैं। अब जब सीपीयू की गति अपनी सीमा तक पहुँच गई है तो यह करने लायक हो सकता है।

मैं जोड़ूंगा: (3) लिंकर अधिक कैशे कुशल समूहन में कार्यों को व्यवस्थित कर सकता है, ताकि महंगे कैशे स्तर को कम से कम किया जा सके। यह विशेष रूप से अनुप्रयोगों के स्टार्टअप समय (सूर्य C ++ संकलक के साथ देखे गए परिणामों के आधार पर) को भी प्रभावित कर सकता है

और यह मत भूलो कि DLL के साथ कोई मृत कोड उन्मूलन नहीं किया जा सकता है। भाषा के आधार पर, DLL कोड इष्टतम भी नहीं हो सकता है। वर्चुअल फ़ंक्शंस हमेशा वर्चुअल होते हैं क्योंकि कंपाइलर को यह नहीं पता होता है कि कोई क्लाइंट इसे ओवरराइट कर रहा है या नहीं।

इन कारणों से, यदि DLL की कोई वास्तविक आवश्यकता नहीं है, तो बस स्थैतिक संकलन का उपयोग करें।

EDIT (टिप्पणी का जवाब देने के लिए, उपयोगकर्ता अंडरस्कोर द्वारा)

यहाँ स्थिति के बारे में एक अच्छा संसाधन है स्वतंत्र कोड समस्या http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-sared-lbooks/

जैसा कि समझाया गया है x86 में उन्हें AFAIK के अलावा किसी और चीज के लिए 15 बिट जंप रेंज नहीं है और बिना शर्त जंप और कॉल के लिए नहीं है। यही कारण है कि कार्य (जनरेटर से) तो 32K हमेशा एक समस्या रही है और एम्बेडेड trampolines की जरूरत है।

लेकिन लिनक्स जैसे लोकप्रिय x86 OS पर आपको .so / DLL फ़ाइल gccस्विच -fpic(जो अप्रत्यक्ष जंप टेबल के उपयोग को लागू करता है) के साथ उत्पन्न नहीं होती है, तो आपको परवाह करने की आवश्यकता नहीं है । क्योंकि यदि आप नहीं करते हैं, तो कोड को सामान्य लिंकर की तरह ही तय किया जाएगा। लेकिन ऐसा करते समय यह कोड सेगमेंट को गैर-साझा करने योग्य बनाता है और इसे डिस्क से मेमोरी में कोड की पूरी मैपिंग की आवश्यकता होती है और इसे उपयोग करने से पहले इसे सभी को छूना चाहिए (अधिकांश कैश को खाली करना, टीएलबी को मारना आदि) एक समय था। जब यह धीमा माना जाता था।

तो आपको अब कोई फायदा नहीं होगा।

मुझे याद है कि क्या ओएस (सोलारिस या FreeBSD) क्योंकि मैं सिर्फ यह नहीं कर रहा था मुझे समस्याओं मेरी यूनिक्स निर्माण प्रणाली के साथ दिया और सोचा कि क्यों यह दुर्घटनाग्रस्त हो गया जब तक मैं लागू किया -fPICकरने के लिए gcc


4
मुझे यह उत्तर पसंद है, क्योंकि प्रश्न में उठाए गए बिंदुओं को संबोधित करने वाला यह एकमात्र था।
एलॉफ

यह दिलचस्प होगा कि उन डीएलएल तकनीकी पर संदर्भ, और विभिन्न ऑपरेटिंग सिस्टम के बीच तुलना।
अंकलजीव

ठीक लगता है, लेकिन सीपीयू की गति निश्चित रूप से अपनी सीमा तक नहीं पहुंची है।
इदियाकापी

67

डायनामिक लिंकिंग एलजीएल जैसी कुछ लाइसेंस आवश्यकताओं को पूरा करने का एकमात्र व्यावहारिक तरीका है


17
जब तक एंड-यूज़र LGPL'd कोड (जैसे कि आप अपने सोर्स कोड या अपने सॉफ़्टवेयर के साथ संकलित ऑब्जेक्ट फ़ाइलों को प्रदान करते हैं) से छुटकारा पा सकते हैं, तो स्थिर लिंकिंग ठीक है । इसके अतिरिक्त, यदि आपका सॉफ़्टवेयर आंतरिक उपयोग के लिए है (अर्थात आपके संगठन के भीतर ही उपयोग किया जाना है, और वितरित नहीं किया गया है), तो आप सांख्यिकीय रूप से लिंक कर सकते हैं। यह उदा सर्वर सर्वर पर लागू होगा, जहाँ सर्वर वितरित नहीं है।
JBentley

3
नहीं मिलता है। क्या आपने जो लिखा है उसकी सराहना करने के लिए आप मुझे और अधिक स्रोत (या अधिक विस्तृत) दे सकते हैं?
बसकाया

4
@ तो LGPL लाइसेंस अनुभाग 4.d + e देखें । आपको या तो एक ऐसे फॉर्म में वितरित करने की आवश्यकता होती है जिसके लिए उपयोगकर्ता को एक लिंक करने की आवश्यकता होती है, या एक साझा (डायनामिक) लाइब्रेरी को वितरित करना होता है।
मार्क रैनसम

46

मैं बिंदु dnmckee उल्लेख के साथ सहमत हूँ, प्लस:

  • वैधानिक रूप से लिंक किए गए एप्लिकेशन को तैनात करना आसान हो सकता है, क्योंकि कम या कोई अतिरिक्त फ़ाइल निर्भरता (.dll / .so) नहीं होती है जो गलत जगह पर गुम या स्थापित होने पर समस्या पैदा कर सकती है।

6
यह ध्यान देने योग्य है कि Google से Go संकलक केवल मुख्य रूप से इस कारण के लिए सांख्यिकीय रूप से संकलित बायनेरिज़ होगा ।
हुत 8

34

सांख्यिकीय रूप से लिंक किए गए निर्माण को करने का एक कारण यह है कि आप निष्पादन योग्य के लिए पूर्ण बंद है, अर्थात सभी प्रतीक संदर्भों को सही तरीके से हल किया गया है।

एक बड़ी प्रणाली के एक भाग के रूप में जिसे निरंतर एकीकरण का उपयोग करके बनाया और परीक्षण किया जा रहा था, रात्रिकालीन प्रतिगमन परीक्षण निष्पादन योग्य के एक सांख्यिकीय रूप से जुड़े संस्करण का उपयोग करके चलाए गए थे। कभी-कभी, हम देखते हैं कि एक प्रतीक हल नहीं करेगा और गतिशील रूप से जुड़े निष्पादन योग्य लिंक सफलतापूर्वक लिंक होने पर भी स्थिर लिंक विफल हो जाएगा।

यह आमतौर पर तब होता था जब साझा किए गए कामों के भीतर गहरे बैठा प्रतीकों का गलत नाम होता था और इसलिए वे सांख्यिकीय रूप से लिंक नहीं होते थे। डायनेमिक लिंकर पूरी तरह से गहराई-पहले या चौड़ाई-पहले मूल्यांकन का उपयोग करने के बावजूद सभी प्रतीकों को पूरी तरह से हल नहीं करता है, इसलिए आप एक गतिशील रूप से जुड़े निष्पादन योग्य के साथ समाप्त कर सकते हैं जिसमें पूर्ण बंद नहीं है।


1
बहुत अच्छी बात है, मैं हाल ही में कुछ कोड के साथ काम करने की कोशिश कर रहा हूं, लेकिन सब कुछ सांख्यिकीय रूप से संकलित करना आश्चर्यजनक रूप से कष्टप्रद साबित हुआ और मैंने बस छोड़ दिया
अंकलजीव

21

1 / मैं उन परियोजनाओं पर गया हूँ जहाँ डायनामिक लिंकिंग बनाम स्टेटिक लिंकिंग को बेंचमार्क किया गया था और अंतर को डायनेमिक लिंकिंग पर स्विच करने के लिए पर्याप्त रूप से निर्धारित नहीं किया गया था (मैं परीक्षण का हिस्सा नहीं था, मुझे अभी निष्कर्ष पता है)

2 / डायनामिक लिंकिंग अक्सर PIC (स्थिति स्वतंत्र कोड, कोड जिसे उस पते के आधार पर संशोधित करने की आवश्यकता नहीं होती है, जिस पर इसे लोड किया जाता है) से जुड़ा होता है। आर्किटेक्चर के आधार पर PIC एक और मंदी ला सकता है लेकिन दो निष्पादन योग्य (और अगर एक सुरक्षा उपाय के रूप में लोड पते के यादृच्छिककरण का उपयोग करता है, तो एक ही निष्पादन योग्य की दो प्रक्रिया के बीच गतिशील रूप से जुड़े पुस्तकालय को साझा करने का लाभ पाने के लिए आवश्यक है)। मुझे यकीन नहीं है कि सभी ओएस दो अवधारणाओं को अलग करने की अनुमति देते हैं, लेकिन सोलारिस और लिनक्स करते हैं और ISTR कि एचपी-यूएक्स भी करते हैं।

3 / मैं अन्य परियोजनाओं पर रहा हूँ जो "आसान पैच" सुविधा के लिए डायनेमिक लिंकिंग का उपयोग करते थे। लेकिन यह "आसान पैच" छोटे फिक्स के वितरण को थोड़ा आसान बनाता है और जटिल एक वर्जनिंग दुःस्वप्न। हम अक्सर ग्राहक साइट पर समस्याओं को ट्रैक करने के लिए सब कुछ पुश करने के लिए समाप्त हो गए क्योंकि गलत संस्करण टोकन था।

मेरा निष्कर्ष यह है कि मैंने स्थैतिक लिंकिंग को छोड़कर उपयोग किया है:

  • प्लगइन्स जैसी चीजों के लिए जो डायनेमिक लिंकिंग पर निर्भर करती हैं

  • जब साझा करना महत्वपूर्ण होता है (C / C ++ रनटाइम, GUI लाइब्रेरी जैसे एक ही समय में कई प्रक्रियाओं द्वारा उपयोग की जाने वाली बड़ी लाइब्रेरी, ... जिन्हें अक्सर स्वतंत्र रूप से प्रबंधित किया जाता है और जिसके लिए ABI को सख्ती से परिभाषित किया जाता है)

यदि कोई "आसान पैच" का उपयोग करना चाहता है, तो मैं तर्क दूंगा कि पुस्तकालयों को ऊपर बड़े पुस्तकालयों की तरह प्रबंधित किया जाना चाहिए: उन्हें लगभग परिभाषित एबीआई के साथ स्वतंत्र होना चाहिए जो कि फिक्स द्वारा नहीं बदलना चाहिए।


1
गैर-पीआईसी या महंगे-पीआईसी प्रोसेसर के लिए कुछ ओएस मेमोरी में एक विशेष पते पर लोड होने के लिए डायनेमिक लाइब्रेरी तैयार करेंगे, और यदि वे ऐसा कर सकते हैं, तो वे लाइब्रेरी की एक कॉपी में हर प्रक्रिया को मैप करते हैं जो इसके साथ लिंक करती है। यह PIC के ओवरहेड को बहुत कम करता है। कम से कम ओएस एक्स और कुछ लिनक्स वितरण ऐसा करते हैं, मुझे विंडोज के बारे में निश्चित नहीं है।
एंड्रयू मैकग्रेगर

धन्यवाद एंड्रयू, मुझे नहीं पता था कि कुछ लिनक्स वितरणों ने इसका उपयोग किया था। क्या आपके पास एक संदर्भ है जिसका मैं अनुसरण कर सकता हूं या एक प्रमुख शब्द जिसे मैं अधिक जानने के लिए खोज सकता हूं? (एफडब्ल्यूआईडब्ल्यू मैंने सुना था कि विंडोज इस का एक प्रकार कर रहा था, लेकिन विंडोज मेरे उल्लेख करने के लिए सक्षमता के मेरे क्षेत्र से बहुत दूर है)।
एपीग्रामग्राम

मुझे लगता है कि आप जिस कीवर्ड की तलाश कर रहे हैं, वह "प्रीलिंक" है - यह प्रोग्राम स्टार्टअप को तेज बनाने के लिए एक लाइब्रेरी को एक निश्चित पते पर जल्दी लोड करने के लिए तैयार करता है।
ब्लेसरॉब्लेड

20

यह लिनक्स और प्रदर्शन प्रभाव पर साझा पुस्तकालयों के बारे में बहुत विस्तार से चर्चा करता है।


3
Drepper के DSO howto से लिंक करने के लिए +1, जिसे लिनक्स पर लाइब्रेरी बनाने वाले सभी को पढ़ना चाहिए।
जनाब

10

यूनिक्स जैसी प्रणालियों पर, डायनेमिक लिंकिंग 'रूट' के लिए आउट-ऑफ-द-वे स्थानों में स्थापित साझा पुस्तकालयों के साथ एक एप्लिकेशन का उपयोग करने के लिए जीवन को मुश्किल बना सकता है। ऐसा इसलिए है क्योंकि डायनेमिक लिंकर आमतौर पर LD_LIBRARY_PATH या रूट विशेषाधिकारों वाली प्रक्रियाओं के लिए इसके समकक्ष ध्यान नहीं देगा। कभी-कभी, तब, स्थैतिक लिंकिंग दिन बचाता है।

वैकल्पिक रूप से, इंस्टॉलेशन प्रक्रिया को पुस्तकालयों का पता लगाना होता है, लेकिन यह सॉफ्टवेयर के कई संस्करणों के लिए मशीन पर सह-अस्तित्व के लिए मुश्किल बना सकता है।


1
LD_LIBRARY_PATHसाझा पुस्तकालयों का उपयोग करने के बारे में बिंदु बिल्कुल बाधा नहीं है, कम से कम जीएनयू / लिनक्स में नहीं। उदाहरण के लिए, यदि आप ../lib/प्रोग्राम फ़ाइल के सापेक्ष निर्देशिका में साझा लाइब्रेरीज़ रखते हैं , तो GNU टूल चेन के साथ लिंकर विकल्प -rpath $ORIGIN/../libउस संबंधित स्थान से लाइब्रेरी की खोज को निर्दिष्ट करेगा। फिर आप आसानी से सभी संबंधित साझा पुस्तकालयों के साथ आवेदन को स्थानांतरित कर सकते हैं। इस ट्रिक का उपयोग करते हुए, एप्लिकेशन और लाइब्रेरीज़ के कई संस्करण होने में कोई समस्या नहीं है (यह मानते हुए कि वे संबंधित हैं, यदि आप प्रतीकात्मक लिंक का उपयोग नहीं कर सकते हैं)।
FooF

> रूट विशेषाधिकारों वाली प्रक्रियाओं के लिए। मुझे लगता है कि आप गैर-रूट उपयोगकर्ताओं से चलाए जाने वाले सेतुइड कार्यक्रमों के बारे में बात कर रहे हैं - अन्यथा इसका कोई मतलब नहीं है। और गैर-मानक स्थानों में पुस्तकालयों के साथ एक सेट्यूइड बाइनरी अजीब है - लेकिन चूंकि केवल रूट उन कार्यक्रमों को स्थापित कर सकता है, वह /etc/ld.so.confउस मामले को भी संपादित कर सकता है ।
ब्लेसरॉब्लेड

10

यह वास्तव में बहुत आसान है। जब आप अपने स्रोत कोड में बदलाव करते हैं, तो क्या आप इसके निर्माण या 20 सेकंड के लिए 10 मिनट इंतजार करना चाहते हैं? बीस सेकंड मैं सभी के साथ रख सकते हैं। इसके अलावा, मैं या तो तलवार निकाल लेता हूं या यह सोचना शुरू कर देता हूं कि कैसे मैं अलग संकलन का उपयोग कर सकता हूं और इसे आराम क्षेत्र में वापस लाने के लिए लिंक कर सकता हूं।


1
मैं वास्तव में संकलन गति में अंतर को बेंचमार्क नहीं किया है, लेकिन अगर यह काफी तेज था, तो मैं गतिशील लिंक चाहूंगा। बूस्ट मेरे संकलन समय के अनुसार पर्याप्त बुरे काम करता है।
एलॉफ

9

डायनेमिक लिंकिंग के लिए सबसे अच्छा उदाहरण है, जब पुस्तकालय प्रयुक्त हार्डवेयर पर निर्भर होता है। प्राचीन समय में सी गणित पुस्तकालय को गतिशील बनाने का निर्णय लिया गया था, ताकि प्रत्येक मंच इसे अनुकूलित करने के लिए सभी प्रोसेसर क्षमताओं का उपयोग कर सके।

एक और भी बेहतर उदाहरण OpenGL हो सकता है। OpenGl एक एपीआई है जिसे AMD और NVidia द्वारा अलग-अलग लागू किया जाता है। और आप एएमडी कार्ड पर एनवीडिया कार्यान्वयन का उपयोग करने में सक्षम नहीं हैं, क्योंकि हार्डवेयर अलग है। आप OpenGL को सांख्यिकीय रूप से अपने प्रोग्राम में लिंक नहीं कर सकते हैं, इस वजह से। डायनामिक लिंकिंग का उपयोग यहां एपीआई को सभी प्लेटफार्मों के लिए अनुकूलित करने के लिए किया जाता है।


8

डायनेमिक लिंकिंग को OS के लिए डायनामिक लाइब्रेरी खोजने और उसे लोड करने के लिए अतिरिक्त समय की आवश्यकता होती है। स्टेटिक लिंकिंग के साथ, सब कुछ एक साथ है और यह मेमोरी में एक-शॉट लोड है।

इसके अलावा, DLL नर्क देखें । यह वह परिदृश्य है जहां DLL कि OS लोड वह नहीं है जो आपके एप्लिकेशन के साथ आया है, या वह संस्करण जो आपके एप्लिकेशन की अपेक्षा है।


1
यह ध्यान रखना महत्वपूर्ण है कि DLL हेल से बचने के लिए काउंटरमेसर की एक श्रृंखला है।
ओदोदे

5

एक अन्य मुद्दा जिस पर अभी तक चर्चा नहीं हुई है, वह है पुस्तकालय में बग को ठीक करना।

स्थैतिक लिंकिंग के साथ, आपको न केवल पुस्तकालय का पुनर्निर्माण करना होगा, बल्कि निष्पादन योग्य को फिर से बनाना और पुनर्वितरित करना होगा। यदि पुस्तकालय केवल एक निष्पादन योग्य में उपयोग किया जाता है, तो यह एक मुद्दा नहीं हो सकता है। लेकिन जितना अधिक निष्पादन योग्य होना आवश्यक है उतना ही दर्द से छुटकारा और पुनर्वितरित करना है, जितना बड़ा दर्द है।

डायनेमिक लिंकिंग के साथ, आप डायनामिक लाइब्रेरी को फिर से बनाते हैं और उसका पुनर्वितरण करते हैं और आप कर रहे हैं।


2

स्टेटिक लिंकिंग आपको केवल एक ही एक्सई देता है, एक बदलाव करने के लिए आपको अपने पूरे प्रोग्राम को फिर से स्थापित करने की आवश्यकता होती है। जबकि डायनेमिक लिंकिंग में आपको केवल dll में परिवर्तन करने की आवश्यकता होती है और जब आप अपना exe चलाते हैं, तो परिवर्तनों को रनटाइम पर उठाया जाएगा। डायनेमिक लिंकिंग द्वारा अपडेट और बग फिक्स प्रदान करना आसान है (जैसे: विंडोज़)।


2

ऐसी कई विशाल और बढ़ती हुई संख्याएँ हैं जहाँ स्थैतिक लिंकिंग का चरम स्तर अनुप्रयोगों और प्रणाली के प्रदर्शन पर बहुत अधिक सकारात्मक प्रभाव डाल सकता है।

मैं संदर्भित करता हूं जिसे अक्सर "एम्बेडेड सिस्टम" कहा जाता है, जिनमें से कई अब सामान्य-उद्देश्य ऑपरेटिंग सिस्टम का उपयोग कर तेजी से बढ़ रहे हैं, और इन प्रणालियों का उपयोग कल्पनाशील सब कुछ के लिए किया जाता है।

एक बहुत ही आम उदाहरण जीएनयू / लिनक्स सिस्टम का उपयोग करने वाले उपकरण हैं जो बिजीबॉक्स का उपयोग करते हैं । मैंने इसे बूट करने योग्य i386 (32-बिट) सिस्टम छवि बनाकर NetBSD के साथ चरम पर ले लिया है, जिसमें कर्नेल और इसकी रूट फाइलसिस्टम दोनों शामिल हैं, बाद वाले में एक एकल स्टैटिक-लिंक्ड (बाय crunchgen) हार्ड-लिंक के साथ बाइनरी शामिल है सभी प्रोग्राम जो कि मानक फुल-फीचर सिस्टम प्रोग्राम्स (टूलकिन को छोड़कर) के सभी (अच्छी तरह से अंतिम गणना 274 पर) शामिल हैं, और यह आकार में 20 मेगा बाइट्स से कम है (और शायद केवल 64 एमबी के साथ सिस्टम में बहुत आराम से चलता है स्मृति की (यहां तक ​​कि रूट फाइल सिस्टम के साथ असम्पीडित और पूरी तरह से रैम में), हालांकि मैं इसे परीक्षण करने के लिए इतना छोटा नहीं खोज पाया हूं।

पहले के पोस्टों में यह उल्लेख किया गया है कि स्टैटिक-लिंक्ड बायनेरिज़ का स्टार्ट-अप समय तेज़ है (और यह बहुत तेज़ हो सकता है ), लेकिन वह केवल तस्वीर का हिस्सा है, खासकर जब सभी ऑब्जेक्ट कोड एक ही में लिंक किए गए हों फ़ाइल, और भी अधिक विशेष रूप से जब ऑपरेटिंग सिस्टम निष्पादन योग्य फ़ाइल से कोड डायरेक्ट की मांग पेजिंग का समर्थन करता है। इस आदर्श परिदृश्य में कार्यक्रमों का स्टार्टअप समय वस्तुतः नगण्य है क्योंकि कोड के लगभग सभी पृष्ठ पहले से ही मेमोरी में होंगे और शेल (और initकिसी भी अन्य पृष्ठभूमि प्रक्रिया जो चल रही हो) के उपयोग में हो सकते हैं, भले ही अनुरोधित प्रोग्राम नहीं किया गया हो कभी भी बूट के बाद से चलाया जा सकता है क्योंकि कार्यक्रम के रनटाइम आवश्यकताओं को पूरा करने के लिए शायद केवल एक पृष्ठ मेमोरी की आवश्यकता होती है।

हालांकि यह अभी भी पूरी कहानी नहीं है। मैं आमतौर पर सभी बायनेरिज़ को स्थिर-लिंक करके मेरे पूर्ण विकास प्रणालियों के लिए नेटबीएसडी ऑपरेटिंग सिस्टम इंस्टॉल का निर्माण और उपयोग करता हूं। भले ही यह सब कुछ के साथ एक जबरदस्त मात्रा में डिस्क स्थान (~ 6.6GB कुल x86_64 के लिए, टूलकिन और X11 स्थिर-लिंक्ड सहित) लेता है (विशेषकर यदि कोई पूर्ण डिबग प्रतीक तालिकाओं को सभी कार्यक्रमों के लिए उपलब्ध रखता है ~ ~ 2.5GB), तो भी परिणाम कुल मिलाकर तेजी से चलता है, और कुछ कार्यों के लिए भी एक विशिष्ट डायनेमिक-लिंक्ड सिस्टम की तुलना में कम मेमोरी का उपयोग करता है जो लाइब्रेरी कोड पृष्ठों को साझा करने के लिए उद्देश्य रखता है। डिस्क सस्ती है (यहां तक ​​कि फास्ट डिस्क), और अक्सर उपयोग की जाने वाली डिस्क फ़ाइलों को कैश करने के लिए मेमोरी भी अपेक्षाकृत सस्ती है, लेकिन सीपीयू चक्र वास्तव में नहीं हैं, और ld.soशुरू होने वाली हर प्रक्रिया के लिए स्टार्टअप लागत का भुगतान करना हरसमय शुरू होने में घंटों और सीपीयू चक्रों के कामों से घंटों का समय लगेगा, जिसमें कई प्रक्रियाओं को शुरू करने की आवश्यकता होती है, खासकर जब एक ही कार्यक्रम का उपयोग किया जाता है, जैसे कि एक विकास प्रणाली पर कंपाइलर। स्टैटिक-लिंक्ड टूलचैन प्रोग्राम पूरे-ओएस मल्टी-आर्किटेक्चर बिल्ड टाइम को घंटों तक कम कर सकते हैं । मुझे अभी तक अपने एकल crunchgen'एड बाइनरी' में टूलकिन का निर्माण करना है , लेकिन मुझे संदेह है कि जब मैं ऐसा करूंगा तो सीपीयू कैश की जीत के कारण बिल्ड टाइम के अधिक घंटे बच जाएंगे।


2

स्टेटिक लिंकिंग में वे फाइलें शामिल हैं जो प्रोग्राम को एक एकल निष्पादन योग्य फ़ाइल में चाहिए।

डायनेमिक लिंकिंग वह है जिसे आप सामान्य रूप से मानते हैं, यह एक निष्पादन योग्य बनाता है जिसके लिए अभी भी DLL की आवश्यकता होती है और जैसे कि एक ही डायरेक्टरी में होना चाहिए (या DLL सिस्टम फ़ोल्डर में हो सकता है)।

(DLL = डायनेमिक लिंक लाइब्रेरी)

गतिशील रूप से जुड़े निष्पादन योग्य तेजी से संकलित किए जाते हैं और संसाधन-भारी नहीं होते हैं।


0

Static linking संकलित समय में एक प्रक्रिया है जब एक लिंक की गई सामग्री को प्राथमिक बाइनरी में कॉपी किया जाता है और एक एकल बाइनरी बन जाता है।

विपक्ष:

  • संकलन समय लंबा है
  • आउटपुट बाइनरी बड़ा है

Dynamic linkingरनटाइम में एक प्रक्रिया है जब एक लिंक की गई सामग्री लोड होती है। यह तकनीकी अनुमति देता है:

  • किसी प्राथमिक को फिर से स्थापित किए बिना लिंक किए गए बाइनरी को अपग्रेड करें जो ABIस्थिरता बढ़ाता है [के बारे में]
  • एक भी साझा प्रति है

विपक्ष:

  • प्रारंभ समय धीमा है (लिंक की गई सामग्री की प्रतिलिपि बनाई जानी चाहिए)
  • लिंकर त्रुटियों को रनटाइम में फेंक दिया जाता है
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.