2008-11-11 10 views
6

यदि मैं इनलाइन फ़ंक्शंस का उपयोग करता हूं, तो क्या स्मृति उपयोग बढ़ता है?सी इनलाइन फ़ंक्शन और मेमोरी उपयोग

+0

सामान्य मामले में यह उत्तरदायी नहीं है। यदि आपके पास एक विशिष्ट उदाहरण है तो इसे आजमाएं और देखें कि क्या होता है। –

उत्तर

2

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

1

इनलाइन फ़ंक्शंस निश्चित रूप से आपके अंतिम निष्पादन योग्य (या बाइनरी) के आकार को बढ़ाता है, क्योंकि वे "कॉपी-पेस्ट" होंगे जिसे आप उन्हें कॉल करते हैं।

+0

मुझे खेद है, लेकिन आपका उत्तर अधूरा है और ऊपर दिए गए उत्तरों में शामिल है। –

0

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

आप क्यों पूछ रहे हैं? आम तौर पर, आप संकलक को यह निर्धारित करने देते हैं कि फ़ंक्शन को रेखांकित किया जाना चाहिए या नहीं; यह आमतौर पर फ़ंक्शन के आकार और जटिलता को देखते हुए बेहतर कॉल कर सकता है।

6

एक अन्य बिंदु आप ध्यान में रखना होगा नहीं है:

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

किसी ने एक अच्छा मुद्दा बनाया: बेहतर संकलक को यह तय करें कि यह कार्य में प्रश्न को रेखांकित करता है या नहीं, क्योंकि यह जानता है कि यह कोड आपके द्वारा बेहतर तरीके से उत्पन्न करता है।

0

फ़ंक्शन कॉल के लिए कई प्रोसेसर निर्देशों की आवश्यकता होती है।

आपको आमतौर पर फ़ंक्शन के लिए प्रत्येक तर्क के लिए एक पुश निर्देश की आवश्यकता होती है, फ़ंक्शन कॉल करने के लिए एक कॉल निर्देश, और अक्सर एक अन्य निर्देश जो फ़ंक्शन कॉल के बाद स्टैक को साफ़ करता है।

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

तो यदि आप जिस फ़ंक्शन को कॉल कर रहे हैं वह केवल कुछ ही निर्देश हैं, तो यह स्मृति को और को तेज़ी से चला सकता है।

ने कहा, इनलाइनिंग के लिए है जब आपका प्रोफाइलर आपको बताता है कि आपको चाहिए।

+0

सी एबीआई को परिभाषित करता है जहां सभी पैरामीटर स्टैक पर धकेल जाते हैं। सी ++ एक विशिष्ट एबीआई को परिभाषित नहीं करता है, जिससे पैरामीटर पासिंग के लिए रजिस्टरों का उपयोग करने के लिए कंपाइलर कार्यान्वयन की अनुमति मिलती है। तो ज्यादातर स्थितियों में सभी पैरामीटर स्टैक पर धकेल दिए जाएंगे। –

2

यह सामान्य मामले में वास्तव में उत्तरदायी नहीं है।

आपके साथ शुरू करने के लिए आम तौर पर इन-लाइनिंग पर नियंत्रण नहीं होता है। यहां तक ​​कि यदि आप फ़ंक्शन इनलाइन को चिह्नित करते हैं, तो यह वास्तव में अभी भी कंपाइलर तक है, यह वास्तव में इन-लाइनिंग (यह केवल एक संकेत है) करेगा।

कंपाइलर कोड को अनुकूलित करने के लिए अपनी पूरी कोशिश करेगा; इन-लाइनिंग का उपयोग करना ऐसा करने में सिर्फ एक उपकरण है। इसलिए छोटे कार्यों को रेखांकित करने से कोड छोटा हो जाएगा (क्योंकि आपको कॉल के लिए पैरामीटर सेट अप करने या रिटर्न वैल्यू पुनर्प्राप्त करने की आवश्यकता नहीं है। लेकिन लंबे कार्यों के साथ भी जवाब पूर्ण नहीं है।

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

मूल रूप से संकलक इसका विश्लेषण करता है और निर्णय लेता है और कार्रवाई का सर्वोत्तम तरीका करता है।

निष्कर्ष। इसके बारे में चिंता मत करो। कंपाइलर आपके से चालाक है और सही काम करेगा।

0

कभी-कभी ऐसा होता है कि हमारे पास पूरे कार्यक्रम में बिखरे हुए कार्य हैं। इस मामले में एक फ़ंक्शन कॉल प्रोग्राम को फ़ंक्शन के पते पर कूदने का कारण बनता है और फ़ंक्शन कॉल समाप्त होने पर वापस आ जाता है। यह कुछ मूल्यवान समय ले जाता है।

उपर्युक्त समस्या इनलाइन फ़ंक्शंस के उपयोग के साथ हल की जा सकती है। इससे संकलक सीधे स्रोत से कोड को कॉल करने का कारण बनता है। इनलाइन फ़ंक्शन कोड के लिए कोई नया मेमोरी निर्देश सेट नहीं बनाया गया है।

हालांकि C++ इनलाइन घोषणा नि: शुल्क है और जब समारोह घोषणा में परिभाषित किया गया है स्वचालित रूप से होता है, ग में यह निम्नलिखित नियमों ::

  1. सी में, आंतरिक संबंध के साथ किसी भी समारोह के द्वारा प्रतिबंधित है इनलाइन घोषित किया जा सकता है, लेकिन बाहरी संबंध के साथ एक समारोह में इनलाइन पर प्रतिबंध है।

  2. यदि इनलाइन कीवर्ड फ़ंक्शन घोषणा में उपयोग किया जाता है, तो फ़ंक्शन परिभाषा एक ही अनुवाद इकाई में उपस्थित होना चाहिए।

इनलाइन डेटाप्रकार function_name (तर्क)

इस कोड को एक गैर इनलाइन समारोह 30% से fastert, बाकी prcessor गति के आधार पर तक चलता है।

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

इनलाइन घोषणा हालांकि मूल्यांकन के आदेश को नष्ट कर देती है, कार्य को आंतरिक नहीं बनाती है। समारोह अभी भी बाहरी है।

कोड आकार — सामान्य, इनलाइन किए जाने वाले कोड कितनी स्मृति अपने कार्यक्रम लोड करने के लिए प्रयोग किया जाता है में वृद्धि होगी में:

8

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

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

इनलाइनिंग ढेर के उपयोग को प्रभावित नहीं करेगा, क्योंकि समान आवंटन और अस्वीकरण इनलाइन कोड के लिए होगा जो गैर-रेखांकित संस्करण के लिए होगा।