अंतरप्रक्रियात्मक अनुकूलन

From alpha
Jump to navigation Jump to search

इंटरप्रोसेड्यूरल ऑप्टिमाइज़ेशन (आईपीओ) छोटे या मध्यम लंबाई के कई अक्सर उपयोग किए जाने वाले फ़ंक्शन (कंप्यूटर विज्ञान) वाले कार्यक्रमों में प्रदर्शन को बेहतर बनाने के लिए कंप्यूटर प्रोग्रामिंग में उपयोग की जाने वाली संकलक तकनीकों का एक संग्रह है। आईपीओ एकल फ़ंक्शन या कोड के ब्लॉक के विपरीत पूरे प्रोग्राम का विश्लेषण करके अन्य कंपाइलर अनुकूलन से भिन्न होता है।

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

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

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

विश्लेषण

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

पठनीयता सहित विभिन्न कारणों से, कार्यक्रमों को अक्सर कई प्रक्रियाओं में विभाजित किया जाता है जो कुछ सामान्य मामलों को संभालते हैं। हालाँकि, प्रत्येक प्रक्रिया की व्यापकता के परिणामस्वरूप विशिष्ट उपयोगों में प्रयास व्यर्थ हो सकता है। अंतरप्रक्रियात्मक अनुकूलन इस अपशिष्ट को कम करने के प्रयास का प्रतिनिधित्व करता है।

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

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

डब्ल्यूपीओ और एलटीओ

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

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

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

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

डब्ल्यूपीओ का बहुत अधिक सीमित रूप एलटीओ के बिना अभी भी संभव है, जैसा कि जीसीसी द्वारा उदाहरण दिया गया है -fwhole-program बदलना। यह मोड जीसीसी को यह मानता है कि संकलित किए जा रहे मॉड्यूल में पूरे प्रोग्राम का प्रवेश बिंदु शामिल है, ताकि इसमें हर दूसरे फ़ंक्शन का बाहरी रूप से उपयोग न किया जा सके और इसे सुरक्षित रूप से अनुकूलित किया जा सके। चूँकि यह केवल एक मॉड्यूल पर लागू होता है, यह वास्तव में पूरे कार्यक्रम को शामिल नहीं कर सकता है। इसे एक-बड़े-मॉड्यूल अर्थ में एलटीओ के साथ जोड़ा जा सकता है, जो तब उपयोगी होता है जब लिंकर जीसीसी को वापस संचार नहीं कर रहा है कि कौन से प्रवेश बिंदु या प्रतीक बाहरी रूप से उपयोग किए जा रहे हैं।[1]


उदाहरण

Program example;
   integer b;              {A variable "global" to the procedure Silly.}
   Procedure Silly(a,x)
      if x < 0 then a:=x + b else a:=-6;
   End Silly;              {Reference to b, not a parameter, makes Silly "impure" in general.}
   integer a,x;            {These variables are visible to Silly only if parameters.}
   x:=7; b:=5;
   Silly(a,x); write(x);
   Silly(x,a); write(x);
   Silly(b,b); write(b);
End example;

यदि सिली के पैरामीटर वैल्यू द्वारा पास # कॉल बाय वैल्यू हैं, तो प्रक्रिया की क्रियाओं का मूल चर पर कोई प्रभाव नहीं पड़ता है, और चूंकि सिली अपने पर्यावरण पर कुछ नहीं करता है (फ़ाइल से पढ़ें, फ़ाइल में लिखें, वैश्विक चर को संशोधित करें जैसे) जैसे बी, आदि) इसके कोड और सभी आमंत्रणों को पूरी तरह से अनुकूलित किया जा सकता है, एक अपरिभाषित (जो कोई फर्क नहीं पड़ता) के मूल्य को छोड़ देता है ताकि बस write कथन बने रहते हैं, केवल स्थिर मान मुद्रित करते हैं।

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

x:=7; b:=5;
if x < 0 then a:=x + b else a:=-6; write(x);   {a is changed.}
if a < 0 then x:=a + b else x:=-6; write(x);   {Because the parameters are swapped.}
if b < 0 then b:=b + b else b:=-6; write(b);   {Two versions of variable b in Silly, plus the global usage.}

कंपाइलर तब इस छोटे से उदाहरण में तर्क के साथ स्थिरांक का अनुसरण कर सकता है (जैसे कि यह है) और पाता है कि यदि-कथनों की भविष्यवाणी स्थिर है और इसलिए...

x:=7; b:=5;
a:=-6; write(7);            {b is not referenced, so this usage remains "pure".}
x:=-1; write(-1);           {b is referenced...}
b:=-6; write(-6);           {b is modified via its parameter manifestation.}

और चूँकि a, b और x के असाइनमेंट बाहरी दुनिया को कुछ भी नहीं देते हैं - वे आउटपुट स्टेटमेंट में दिखाई नहीं देते हैं, न ही बाद की गणनाओं के इनपुट के रूप में (जिनके परिणाम बदले में आउटपुट की ओर ले जाते हैं, अन्यथा वे भी अनावश्यक हैं) - वहाँ है इस कोड का भी कोई मतलब नहीं है, और नतीजा यह है

write(7);
write(-1);
write(-6);

संदर्भ द्वारा प्रतीत होने वाले मापदंडों को पारित करने के लिए एक भिन्न विधि मूल्यांकन रणनीति#कॉपी-रिस्टोर द्वारा कॉल करें|कॉपी-इन, कॉपी-आउट है जिसके तहत प्रक्रिया उन मापदंडों की स्थानीय प्रतिलिपि पर काम करती है जिनके मान बाहर निकलने पर मूल में वापस कॉपी किए जाते हैं प्रक्रिया से. यदि प्रक्रिया में एक ही पैरामीटर तक पहुंच है लेकिन अलग-अलग तरीकों से जैसे कि सिली (ए, ए) या सिली (ए, बी) जैसे आह्वान में, विसंगतियां उत्पन्न हो सकती हैं। इसलिए, यदि पैरामीटर कॉपी-इन, कॉपी-आउट द्वारा बाएं से दाएं क्रम में पारित किए गए थे तो सिली (बी, बी) का विस्तार होगा

p1:=b; p2:=b;                               {Copy in. Local variables p1 and p2 are equal.}
if p2 < 0 then p1:=p2 + b else p1:=-6;      {Thus p1 may no longer equal p2.}
b:=p1; b:=p2;                               {Copy out. In left-to-right order, the value from p1 is overwritten.}

और इस मामले में, p1 (जिसे बदल दिया गया है) के मान को b में कॉपी करना व्यर्थ है, क्योंकि इसे तुरंत p2 के मान से अधिलेखित कर दिया जाता है, जो मान b के मूल मान से प्रक्रिया के भीतर संशोधित नहीं किया गया है, और इसी तरह तीसरा कथन बन जाता है

write(5);          {Not -6}

व्यवहार में इस तरह के अंतर से उलझन पैदा होने की संभावना है, जो मापदंडों की प्रतिलिपि बनाने के क्रम के सवालों से और भी बढ़ जाती है: क्या इसे बाहर निकलने के साथ-साथ प्रवेश पर भी बाएं से दाएं किया जाएगा? इन विवरणों को संभवतः संकलक मैनुअल में सावधानीपूर्वक नहीं समझाया गया है, और यदि वे हैं, तो संभवतः उन्हें तत्काल कार्य के लिए प्रासंगिक नहीं होने के कारण छोड़ दिया जाएगा और समस्या उत्पन्न होने तक लंबे समय तक भुला दिया जाएगा। यदि (जैसी संभावना है) अस्थायी मान स्टैक स्टोरेज योजना के माध्यम से प्रदान किए जाते हैं, तो यह संभावना है कि कॉपी-बैक प्रक्रिया कॉपी-इन के विपरीत क्रम में होगी, जिसका इस उदाहरण में मतलब होगा कि पी1 अंतिम होगा इसके बजाय मान b पर लौटा दिया गया।

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

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

सामान्य तौर पर

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

कुछ कंप्यूटर भाषाएं मापदंडों के उपयोग के बारे में दावा करने में सक्षम (या यहां तक ​​कि आवश्यकता) करती हैं, और यह घोषित करने का अवसर भी प्रदान कर सकती हैं कि चर के मान कुछ सेट तक ही सीमित हैं (उदाहरण के लिए, 6 < x ≤ 28) इस प्रकार के लिए और अधिक सहायता प्रदान करते हैं अनुकूलन प्रक्रिया को पूरा करना, और भूलों का पता लगाने के लिए स्रोत कोड की सुसंगतता पर सार्थक जांच भी प्रदान करना। लेकिन यह कभी भी पर्याप्त नहीं है - केवल कुछ चर को सरल बाधाएं दी जा सकती हैं, जबकि अन्य को जटिल विशिष्टताओं की आवश्यकता होगी: यह कैसे निर्दिष्ट किया जा सकता है कि चर पी एक अभाज्य संख्या है, और यदि ऐसा है, तो मान 1 शामिल है या नहीं? जटिलताएँ तत्काल हैं: महीने के दिन D के लिए मान्य सीमाएँ क्या हैं, यह देखते हुए कि M एक महीने की संख्या है? और क्या सभी उल्लंघन तत्काल समाप्ति के योग्य हैं? अगर यह सब संभाला भी जा सके, तो क्या लाभ हो सकता है? और किस कीमत पर? पूर्ण विशिष्टताएँ प्रोग्राम के फ़ंक्शन को किसी अन्य रूप में पुनः प्रस्तुत करने के समान होंगी और कंपाइलर द्वारा उन्हें संसाधित करने में लगने वाले समय के अलावा, वे इस प्रकार बग के अधीन होंगे। इसके बजाय, रन-टाइम रेंज जांच के साथ केवल सरल विशिष्टताओं की अनुमति है।

ऐसे मामलों में जहां कोई प्रोग्राम कोई इनपुट नहीं पढ़ता है (जैसा कि उदाहरण में है), कोई कल्पना कर सकता है कि कंपाइलर के विश्लेषण को आगे बढ़ाया जा रहा है ताकि परिणाम प्रिंट स्टेटमेंट की एक श्रृंखला से अधिक न हो, या संभवतः कुछ लूप तेजी से ऐसे मान उत्पन्न कर रहे हों। क्या यह तब अभाज्य संख्याएँ उत्पन्न करने के लिए एक कार्यक्रम को पहचानेगा, और ऐसा करने के लिए सबसे प्रसिद्ध विधि में परिवर्तित करेगा, या, इसके बजाय एक पुस्तकालय का संदर्भ प्रस्तुत करेगा? असंभावित! सामान्य तौर पर, इसे रोकने के लिए मनमाने ढंग से जटिल विचार उत्पन्न होते हैं (निर्णय की समस्या), और केवल सीमित सुधारों के साथ कोड को चलाने के अलावा कोई विकल्प नहीं है।

इतिहास

ऐसा प्रतीत होता है कि ALGOL जैसी प्रक्रियात्मक भाषाओं के लिए, अंतरप्रक्रियात्मक विश्लेषण और अनुकूलन 1970 के दशक की शुरुआत में व्यावसायिक अभ्यास में प्रवेश कर गए थे। आईबीएम के पीएल/आई ऑप्टिमाइज़िंग कंपाइलर ने प्रक्रिया कॉल और अपवाद (स्थितियों के अनुसार पीएल/आई शब्दों में कास्ट) दोनों के दुष्प्रभावों को समझने के लिए अंतरप्रक्रियात्मक विश्लेषण किया।[3] और फ़्रांसिस ई. एलन द्वारा कागजात में।[4][5] एपीएल (प्रोग्रामिंग भाषा) प्रोग्रामिंग भाषा के संकलन पर काम आवश्यक रूप से अंतरप्रक्रियात्मक था।[6][7] अंतरप्रक्रियात्मक विश्लेषण और अनुकूलन की तकनीकें 1980 और 1990 के दशक में अकादमिक अनुसंधान का विषय थीं। वे 1990 के दशक की शुरुआत में उत्तल कंप्यूटर निगम (कॉनवेक्स सी4 के लिए एप्लिकेशन कंपाइलर) और अर्देंट (उत्साही टाइटन के लिए कंपाइलर) दोनों के कंपाइलरों के साथ वाणिज्यिक कंपाइलर दुनिया में फिर से उभरे। इन कंपाइलरों ने प्रदर्शित किया कि व्यावसायिक कंपाइलर में स्वीकार्य होने के लिए प्रौद्योगिकियों को पर्याप्त तेजी से बनाया जा सकता है; बाद में अंतरप्रक्रियात्मक तकनीकें कई वाणिज्यिक और गैर-वाणिज्यिक प्रणालियों में सामने आई हैं।

झंडे और कार्यान्वयन

यूनिक्स जैसा

जीएनयू कंपाइलर कलेक्शन में सभी अनुकूलन स्तरों पर फ़ंक्शन इनलाइनिंग है। पर -O1 यह केवल उन लोगों पर लागू होता है जिन्हें केवल एक बार बुलाया जाता है (-finline-functions-once), पर -O2 इस बाधा में ढील दी गई है (-finline-functions). डिफ़ॉल्ट रूप से यह एकल-फ़ाइल-केवल व्यवहार है, लेकिन लिंक-टाइम अनुकूलन के साथ -flto यह पूरा प्रोग्राम बन जाता है.[1]बजना का कमांड-लाइन इंटरफ़ेस जीसीसी के समान है, सिवाय इसके कि कोई अपवाद नहीं है -fwhole-program विकल्प।[8] एलटीओ द्वारा उत्पादित ऑब्जेक्ट फ़ाइलों में एक कंपाइलर-विशिष्ट मध्यवर्ती प्रतिनिधित्व (आईआर) होता है जिसे लिंक-टाइम पर व्याख्या किया जाता है। यह सुनिश्चित करने के लिए कि यह स्थैतिक पुस्तकालयों के साथ अच्छी तरह से चलता है, नए जीएनयू लिंकर्स में एक लिंकर प्लगइन इंटरफ़ेस होता है जो कंपाइलर को जरूरत पड़ने पर ऑब्जेक्ट फ़ाइलों को मशीन कोड फॉर्म में परिवर्तित करने की अनुमति देता है। यह प्लगइन सामान्य रूप से एलटीओ प्रक्रिया को चलाने में भी मदद करता है। वैकल्पिक रूप से, मशीन कोड और आईआर दोनों को शामिल करने के लिए एक मोटा एलटीओ ऑब्जेक्ट तैयार किया जा सकता है, लेकिन इसमें अधिक जगह लगती है।[1]

चूंकि जीसीसी और एलएलवीएम (क्लैंग) दोनों विभिन्न प्रोग्रामिंग भाषाओं से आईआर उत्पन्न करने में सक्षम हैं, लिंक-टाइम आईपीओ भाषा सीमाओं के पार भी हो सकता है। यह आमतौर पर C और C++ के साथ प्रदर्शित किया जाता है,[9] लेकिन एलएलवीएम रस्ट (प्रोग्रामिंग भाषा) और अन्य सभी एलएलवीएम-आधारित कंपाइलरों के लिए भी इसे संभव बनाता है।[10]


गैर-एलटीओ विकल्प

जीसीसी और क्लैंग अनुकूलन स्तर 2 पर डिफ़ॉल्ट रूप से आईपीओ निष्पादित करते हैं। हालांकि, एलटीओ अक्षम होने पर अनुकूलन की डिग्री सीमित होती है, क्योंकि आईपीओ केवल ऑब्जेक्ट फ़ाइल के भीतर ही हो सकता है और गैर-स्टेटिक (कीवर्ड) फ़ंक्शन को कभी भी समाप्त नहीं किया जा सकता है। बाद वाली समस्या का एक गैर-एलटीओ समाधान है: -fwhole-program स्विच का उपयोग केवल यही मानने के लिए किया जा सकता है main() गैर-स्थैतिक है, अर्थात बाहर से दिखाई देता है।[11] एक अन्य गैर-एलटीओ तकनीक फ़ंक्शन सेक्शन है (-ffunction-sections जीसीसी और क्लैंग में)। प्रत्येक फ़ंक्शन को ऑब्जेक्ट फ़ाइल में अपने स्वयं के अनुभाग में रखकर, लिंकर गैर-संदर्भित अनुभागों को हटाकर (लिंकर विकल्प का उपयोग करके) आईआर के बिना मृत कोड को हटा सकता है --gc-sections).[12] एक समान विकल्प वेरिएबल्स के लिए उपलब्ध है, लेकिन इससे बहुत खराब कोड उत्पन्न होता है।

अन्य

इंटेल सी++ कंपाइलर|इंटेल सी/सी++ कंपाइलर संपूर्ण-प्रोग्राम आईपीओ की अनुमति देते हैं। एकल फ़ाइल के लिए अंतरप्रक्रियात्मक अनुकूलन को सक्षम करने वाला ध्वज है -ip, प्रोग्राम में सभी फ़ाइलों में अंतरप्रक्रियात्मक अनुकूलन को सक्षम करने के लिए ध्वज है -ipo.[13][14] विज़ुअल स्टूडियो में एकीकृत Microsoft विज़ुअल C++, पूरे प्रोग्राम पर अंतरप्रक्रियात्मक अनुकूलन का भी समर्थन करता है।[15] संपूर्ण-प्रोग्राम अंतरप्रक्रियात्मक अनुकूलन को सक्षम करने के लिए एक कंपाइलर-स्वतंत्र इंटरफ़ेस इसके माध्यम से है INTERPROCEDURAL_OPTIMIZATION सीएमके में संपत्ति।[16]


यह भी देखें

संदर्भ

  1. 1.0 1.1 1.2 1.3 1.4 "विकल्प अनुकूलित करें". Using the GNU Compiler Collection (GCC). Link-time optimizations do not require the presence of the whole program to operate. If the program does not require any symbols to be exported, it is possible to combine -flto and -fwhole-program to allow the interprocedural optimizers to use more aggressive assumptions which may lead to improved optimization opportunities. Use of -fwhole-program is not needed when linker plugin is active (see -fuse-linker-plugin).
  2. "एलटीओ अवलोकन". GNU Compiler Collection (GCC) Internals.
  3. Thomas C. Spillman, "Exposing side effects in a PL/I optimizing compiler", in Proceedings of IFIPS 1971, North-Holland Publishing Company, pages 376-381.
  4. Frances E. Allen, "Interprocedural Data Flow Analysis", IFIPS Proceedings, 1974.
  5. Frances E. Allen, and Jack Schwartz, "Determining the Data Flow Relationships in a Collection of Procedures", IBM Research Report RC 4989, Aug. 1974.
  6. Philip Abrams, "An APL Machine", Stanford University Computer Science Department, Report STAN-CS-70-158, February, 1970.
  7. Terrence C. Miller, "Tentative Compilation: A Design for an APL Compiler", Ph.D. Thesis, Yale University, 1978.
  8. "क्लैंग कमांड लाइन तर्क संदर्भ". Clang 11 documentation.
  9. Reinhart, Jonathan. "जीसीसी या क्लैंग के लिए एलटीओ सी और सी++ विधियों में अनुकूलन कर सकता है". Stack Overflow.
  10. Woerister, Michael (19 September 2019). "Closing the gap: cross-language LTO between Rust and C/C++". LLVM Dev Blog.
  11. "विकल्प अनुकूलित करें". Using the GNU Compiler Collection (GCC).
  12. "कार्य अनुभाग". elinux.org.
  13. "Intel compiler 8 documentation". Archived from the original on 2006-09-21. Retrieved 2007-02-13.
  14. Intel Visual Fortran Compiler 9.1, Standard and Professional Editions, for Windows* - Intel Software Network
  15. "/GL (Whole Program Optimization)". Microsoft Docs. 2019-03-12. Retrieved 2020-01-26.
  16. "INTERPROCEDURAL_OPTIMIZATION". CMake 3.17.2 Documentation.


बाहरी संबंध