2011-09-18 18 views
13

मैं कुछ काम करता है, कोड का लगभग दो सरल रेखाओं में से प्रत्येक के लिए है कहो, और वे इस तरह एक दूसरे को फोन: ACD कॉल B कॉल कॉल ... K कहता है। (इसलिए मूल रूप से यह छोटी फ़ंक्शन कॉल की एक लंबी श्रृंखला है।) इन फ़ंक्शंस को इनलाइन करने के लिए आमतौर पर कॉल पेड़ में कितने गहरे होंगे?कंपाइलर इनलाइन फ़ंक्शन कितने गहरे काम करते हैं?

+0

आप बस परीक्षण और असेंबली देख सकते हैं! आपके कंपाइलर दस्तावेज़ आपको बताएंगे कि इनलाइनिंग गहराई को कैसे निर्दिष्ट किया जाए; मुझे लगता है कि यह डिफ़ॉल्ट रूप से जीसीसी के लिए 50 की तरह कुछ है। –

+2

मेरा मानना ​​है कि यह संकलक विशिष्ट होना चाहिए और आप अपने कंपाइलर की कोई जानकारी पोस्ट नहीं करते हैं। –

+1

एमएसवीसी के तहत आपके पास '#pragma inline_depth' (http://msdn.microsoft.com/en-us/library/cx053bca.aspx) का उपयोग करके इस पर आंशिक नियंत्रण है, हालांकि मुझे कुछ स्थितियों में इसकी समस्याएं हैं (जैसे रिकर्सिव इनलाइनिंग, जो संभव होने के लिए है, लेकिन कभी काम नहीं किया, मैन्युअल रूप से इसे समाप्त कर दिया) – Necrolis

उत्तर

12

प्रश्न सार्थक नहीं है।

आप इनलाइनिंग के बारे में सोचते हैं, और उसके परिणामों के लिए, आप यह महसूस करेंगे: (सभी रजिस्टर बचत/फ्रेम समायोजन के साथ)

  • बचते एक समारोह कॉल
  • अनुकूलक की अधिक जानकारी मिलती उजागर (मृत स्टोर, मृत कोड, आम उप अभिव्यक्ति elimintation ...)
  • डुप्लिकेट कोड (अनुदेश कैश और निष्पादन योग्य आकार, अन्य बातों के अलावा सूजन)

यह तय करते चाहे इनलाइन या नहीं, संकलक इस प्रकार संभावित ब्लोट बनाया गया और गति लाभ की उम्मीद के बीच संतुलित संतुलन करता है। यह संतुलन अधिनियम विकल्पों से प्रभावित होता है: जीसीसी -O3 के लिए गति के लिए अनुकूलन का मतलब है -Oz का आकार आकार के लिए अनुकूलन है, इनलाइनों पर इन्हें विपरीत विपरीत व्यवहार हैं!

इसलिए, "घोंसला स्तर" क्या मायने रखता है यह निर्देश की संख्या नहीं है (संभवतः भारित सभी के बराबर नहीं बनाया जाता है)।

इसका मतलब यह है कि एक साधारण अग्रेषण समारोह:

int foo(int a, int b) { return foo(a, b, 3); } 

अनिवार्य रूप से देखने को इनलाइन बिंदु से "पारदर्शी" है।

एक तरफ, कोड की सौ पंक्तियों की गणना करने वाला फ़ंक्शन इनलाइन होने की संभावना नहीं है। सिवाय इसके कि static नि: शुल्क फ़ंक्शंस केवल एक बार बुलाया जाता है, जिसे व्यवस्थित रूप से रेखांकित किया जाता है, क्योंकि यह इस मामले में कोई भी डुप्लिकेशन नहीं बनाता है।

इस दो उदाहरण से हम कैसे heuristics किस प्रकार व्यवहार करते कूबड़ मिलती है:

  • कम निर्देश समारोह है,
  • कम अक्सर inling के लिए बेहतर यह कहा जाता है,
  • इनलाइन करने के लिए बेहतर

उसके बाद, वे मापदंड हैं आप या कोई अन्य (__force_inline के रूप में MSVC जो दृढ़ता से inling पर संकेत, gcc एक तरह से प्रभावित करने के लिए सेट करने के लिए सक्षम होना चाहिए के रूप में वे -finline-limit झंडा Tresh "उठाना" के लिए गिनती निर्देश, आदि ...)


एक स्पर्शरेखा पर पर पुराने: आप के बारे में आंशिक इनलाइनिंग में पता है?

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

उदाहरण के लिए:

void foo(Bar* x) { 
    if (not x) { return; } // null pointer, pfff! 

    // ... BIG BLOC OF STATEMENTS ... 
} 

void bar(Bar* x) { 
    // DO 1 
    foo(x); 
    // DO 2 
} 

सकता है के रूप में "अनुकूलित" हो:

void [email protected](Bar* x) { 
    // ... BIG BLOC OF STATEMENTS ... 
} 

void bar(Bar* x) { 
    // DO 1 
    if (x) { [email protected](x); } 
    // DO 2 
} 
बेशक

, एक बार फिर इनलाइन किए जाने वाले heuristics लागू होते हैं, लेकिन वे और अधिक discriminately लागू!


और अंत में, जब तक कि आप WPO (साबुत कार्यक्रम अनुकूलन) या LTO (लिंक समय अनुकूलन) का उपयोग, कार्य केवल तभी उनकी परिभाषा ही टीयू (अनुवाद यूनिट) में है inlined जा सकती है कॉल साइट है कि।

+0

मैं आमतौर पर ऐसा नहीं करता, लेकिन मुझे लगता है कि मुझे स्वीकृत उत्तर बदलना चाहिए। :) मुझे आंशिक रूपरेखा के बारे में पता नहीं था और न ही कॉल की संख्या के आधार पर इनलाइनिंग के बारे में पता था। विवरण के लिए धन्यवाद। –

7

मैंने कंपाइलर्स को 5 से अधिक कार्यों को गहराई से देखा है। लेकिन किसी बिंदु पर, यह मूल रूप से एक अंतरिक्ष-दक्षता व्यापार-बंद बन जाता है जो संकलक बनाता है। इस पहलू में प्रत्येक कंपाइलर अलग है। दृश्य स्टूडियो इनलाइनिंग के साथ बहुत रूढ़िवादी है। जीसीसी (अंडर-ओ 3) और इंटेल कंपाइलर इनलाइन करना पसंद करते हैं ...

+0

जीसीसी में आईआईआरसी यह कार्य के लिए कुछ अनुमानित "निर्देश गणना" पर निर्भर करता है (यानी वास्तव में यह कितना समय है); घोंसला स्तर जो मैंने दस्तावेज़ों ('-फिनलाइन-सीमा' और दोस्तों) में पढ़ा है, उसमें से भूमिका निभाता नहीं है, इस अर्थ में कि लंबाई 10 का कार्य 5 + नेस्टेड 5 जैसा ही रेखांकित किया जाएगा। – eudoxos

+1

यदि फ़ंक्शंस को कॉल किया जाता है केवल एक बार इनलाइन से बचने का कोई कारण नहीं है। प्रोफ़ाइल प्रतिक्रिया का कहना है कि जीसीसी आक्रामक रूप से इनलाइन भी होगी। –

+3

@Zan लिंक्स: यह ज्यादातर सही है। कुछ मामले हैं, जहां इनलाइन नहीं करना बेहतर है। यदि फ़ंक्शन एक प्रदर्शन-महत्वपूर्ण लूप में है और इसे शायद ही कभी (एक जाल हैंडलर की तरह) कहा जाता है, तो लूप को छोटे आकार के कोड-आकार को रखने के लिए इसे बेहतर नहीं करना बेहतर होता है। (यह कभी-कभी आपको लंबी-कूद के बजाए शॉर्ट-कूद का उपयोग करने की अनुमति देगा) – Mysticial

संबंधित मुद्दे