2010-01-15 13 views
15

मैं लिनक्स पर एक mingw32 क्रॉस कंपाइलर का उपयोग करके, एक विशेष रूप से बड़ी फ़ाइल (~ 15 के लाइन) सहित कई ऑटो-जेनरेट कोड बना रहा हूं। अधिकांश फ़ाइलें बेहद तेज़ होती हैं, लेकिन यह एक बड़ी फ़ाइल संकलित करने के लिए अप्रत्याशित रूप से लंबे समय तक (~ 15 मिनट) लेती है।मुझे कैसे पता चलेगा कि g ++ किसी विशेष फ़ाइल पर बहुत लंबा समय क्यों लेता है?

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

अफसोस की बात है कि मेरे पास इस क्रॉस-कंपाइलर को पुनर्निर्माण करने की क्षमता नहीं है, इसलिए कंपाइलर को डिबगिंग जानकारी जोड़ना और इसके माध्यम से कदम उठाना एक संभावना नहीं है।

क्या फाइल में है:

  • का एक समूह
  • स्ट्रिंग तुलना
  • if-then चेक और निर्माता आमंत्रण

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


-ftime-रिपोर्ट के परिणाम के रूप में नील बटरवर्थ ने सुझाव दिया, संकेत मिलता है कि "जीवन विश्लेषण" चरण 921 सेकंड है, जो 15 मिनट के सबसे तक ले जाता है ले जा रहा है।

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

हमें लगता है कि फ़ंक्शन पॉइंटर्स के नामों के मानचित्र में इंगित करने के लिए इसे बदलना कुछ चीजों को बेहतर बना सकता है, इसलिए हम इसे आजमा सकते हैं।


दरअसल, कारखाने कार्यों का एक गुच्छा (वस्तु के अनुसार) पैदा करने और के बारे में 25 सेकंड के लिए मूल 15 मिनट से अपने कारखाने समारोह कम संकलन समय के लिए सूचक को वस्तु की स्ट्रिंग नाम से एक नक्शा बनाने, जो हर किसी को अपने निर्माण पर बहुत समय बचाएगा।

बार-बार-रिपोर्ट के बारे में टिप के लिए नील बटरवर्थ को धन्यवाद।

+0

इस पर एक नज़र डालें: http: //stackoverflow.com/questions/318398/why-does-c-compilation-take-so-long –

+0

क्या आप हमें बता सकते हैं कि फ़ाइल में क्या है? इनलाइन फ़ंक्शन? Enums? परिभाषित करता है? शामिल है और मैक्रो सूचियां? उनमें से कितने? – Coincoin

+0

यदि आप स्थानीय कंपाइलर का उपयोग करते हैं तो क्या आपको वही समस्या मिलती है? यदि ऐसा है, तो आप यह सुनिश्चित कर सकते हैं कि प्रोफाइल कहां खर्च किया गया है, यह देखने के लिए सक्षम प्रोफाइलिंग के साथ। –

उत्तर

24

आपके द्वारा इच्छित सभी विवरण नहीं देगा, लेकिन -v (verbose) और -ftime-report झंडे के साथ चलने का प्रयास करें। उत्तरार्द्ध संकलक का क्या सारांश रहा है इसका सारांश प्रस्तुत करता है।

+0

-टाइम-रिपोर्ट मुझे आवश्यक सुराग था। – Schamp

3

इसमें शायद सबसे अधिक शामिल हैं। मेरा मानना ​​है कि -एमडी किसी दिए गए सीपीपी फ़ाइल में सभी शामिल फ़ाइलों को सूचीबद्ध करेगा (इसमें शामिल हैं और आगे भी शामिल हैं)।

+0

++ हां। नेस्टेड में शामिल हैं और टेम्पलेट प्रीप्रोसेसर को एक सुखद सवारी पर भेज सकते हैं। कम से कम शामिल किए गए हेडर्स के साथ शामिल किया जा सकता है। –

2

सामान्य रूप से g ++ नीचे धीमे होते हैं टेम्पलेट्स। उदाहरण के लिए बूस्ट का उपयोग करना पसंद करता है। इसका मतलब है अच्छा कोड, शानदार प्रदर्शन लेकिन खराब संकलन गति।

दूसरी तरफ, 15 मिनट बहुत लंबा लगता है। एक त्वरित googling के बाद, ऐसा लगता है कि यह mingw

+0

नहीं बस mingw। मैंने लिनक्स जीसीसी और विजुअल स्टूडियो को उतना ही बुरा व्यवहार किया है। फिर फिर, यह केवल एक बार संकलित स्रोत संकुल था, इसलिए कंप्यूटर्स के पास इसे गति देने का मौका नहीं था। – luiscubal

+0

@ ट्रिस्ट्रम क्या था आपकी Google खोज स्ट्रिंग? – Schamp

1

कोशिश करने की एक और प्रक्रिया लंबे समय से चल रहे कोड के हिस्से को फँसाने के लिए "प्रगति मार्कर" pragma एस को जोड़ने के लिए है। विजुअल स्टूडियो कंपाइलर #pragma message() प्रदान करता है, हालांकि ऐसा करने के लिए मानक प्रगति नहीं है।

कोड की शुरुआत में एक मार्कर रखें और कोड के अंत में एक मार्कर रखें। एंड मार्कर #error हो सकता है क्योंकि आपको स्रोत फ़ाइल के शेष की परवाह नहीं है। सबसे लंबे समय तक कोड के अनुभाग को जाल के अनुसार मार्करों को तदनुसार ले जाएं।

बस एक सोचा ...

1

मैं #if 0/#endif संकलन से स्रोत फ़ाइल के बड़े हिस्से को खत्म करने का उपयोग करेंगे। कोड के विभिन्न ब्लॉक के साथ दोहराएं जब तक आप यह निर्धारित न करें कि कौन से ब्लॉक धीमे हैं। स्टार्टर्स के लिए, आप देख सकते हैं कि #include#if 0/#endif का उपयोग कर समस्या है, लेकिन #include के सभी चीज़ों को बाहर करने के लिए समस्या है।

0

@Goz और @Josh_Kelley से संबंधित, आप प्री-प्रोसेस किए गए स्रोत (#includes इनलाइन के साथ) -E का उपयोग करके जीसीसी/जी ++ प्राप्त कर सकते हैं। यह निर्धारित करने का एक तरीका है कि आपका स्रोत कितना बड़ा है।

और यदि संकलक स्वयं समस्या है, तो आप संकलन कमांड को चिपकाने में सक्षम हो सकते हैं जो यह देखने के लिए काफी समय ले रहा है कि कोई विशेष फ़ाइल पहुंच है या एक विशिष्ट आंतरिक कार्रवाई है जो लंबे समय से ले रही है।

0

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

एक स्रोत में 15K लाइनें बहुत अधिक है, लेकिन अगर विभाजित हो, तो भी उस कोड को संकलित करने की आवश्यकता है; हालांकि एक वृद्धिशील निर्माण का उपयोग करने का मतलब यह हो सकता है कि इसे हर समय संकलन करने की आवश्यकता नहीं है। बड़ी फ़ाइल की आवश्यकता नहीं है; यह सिर्फ खराब अभ्यास/डिजाइन है। जब मैं फ़ाइल को 500 लाइनों तक प्राप्त करता हूं तो बेहतर मॉड्यूलरिसेशन के बारे में सोचना शुरू करता हूं (हालांकि मैं इसके बारे में डॉगमैटिक नहीं हूं)

0

संकलन के दौरान देखने के लिए एक बात यह है कि आपके कंप्यूटर में कितनी मेमोरी है। यदि कंपाइलर इतनी मेमोरी आवंटित करता है कि कंप्यूटर स्वैपिंग शुरू हो जाता है, तो समय संकलित करें, रास्ता बढ़ जाएगा।

यदि आप ऐसा देखते हैं, तो आसानी से समाधान अधिक रैम स्थापित करना है ... या फ़ाइल को कई हिस्सों में विभाजित करें जिसे अलग से संकलित किया जा सकता है।

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