क्या यह वास्तव में विकास और डिबगिंग चरणों के दौरान एक अच्छा अभ्यास अक्षम अनुकूलन है?


15

मैंने C में 16-बिट PIC माइक्रोकंट्रोलर के प्रोग्रामिंग पढ़े हैं , और पुस्तक में इस बात की पुष्टि है:

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

मैं मानता हूँ कि मैं थोड़ा उलझन में था। मुझे समझ नहीं आया कि क्या लेखक ने कहा है कि C30 मूल्यांकन अवधि के कारण या अगर यह वास्तव में एक अच्छा अभ्यास है।

मैं जानना चाहता हूं कि क्या आप वास्तव में इस अभ्यास का उपयोग करते हैं, और क्यों?

जवाबों:


16

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

यह भी महसूस हो सकता है कि आप एक संख्या की गणना करते हैं, जिसे आप ओवर राइटिंग से पहले कुछ भी नहीं करते हैं। उस मामले में, यह बेकार गणना को समाप्त कर सकता है।

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

आपको इससे सावधान रहने की ज़रूरत है, हालाँकि, आपके कोड के आधार पर, अनुकूलन चीजों को तोड़ सकता है! सामान्य कोड में जो एक सही ढंग से कार्य करने वाले ऑप्टिमाइज़र द्वारा टूट गया है, वास्तव में सिर्फ छोटी गाड़ी का कोड है जो किसी चीज़ से दूर हो रहा है, इसलिए आप आमतौर पर यह पता लगाना चाहते हैं कि ऑप्टिमाइज़र इसे क्यों तोड़ता है।


5
इस तर्क का प्रतिवाद यह है कि ऑप्टिमाइज़र की संभावना चीज़ों को छोटा और / या अधिक तेज़ कर देगी, और यदि आपको समय या आकार की अड़चन कोड मिल गया है, तो आप अनुकूलन को अक्षम करके कुछ तोड़ सकते हैं, और अपना समय बर्बाद कर सकते हैं जिससे कोई समस्या नहीं आती है ' टी वास्तव में मौजूद हैं। बेशक, डिबगर आपके कोड को धीमा और बड़ा बना सकता है।
केविन वर्मेयर

मैं इसके बारे में और कहाँ जान सकता हूँ?
डेनियल ग्रिलो

मैंने C30 संकलक के साथ काम नहीं किया है, लेकिन C18 संकलक के लिए संकलक के लिए एक ऐप नोट / मैनुअल था जो इसमें शामिल किए गए अनुकूलन का समर्थन करता है।
मार्क

@O Engenheiro: यह क्या अनुकूलन का समर्थन करता है के लिए अपने संकलक डॉक्स की जाँच करें। अनुकूलन संकलक, पुस्तकालयों और लक्ष्य वास्तुकला के आधार पर बेतहाशा भिन्न होता है।
माइकल कोहेन

फिर से, C30 संकलक के लिए नहीं, लेकिन जीसीसी विभिन्न अनुकूलन के एक लंबी सूची को प्रकाशित करता है जिसे लागू किया जा सकता है। यदि आप एक विशेष नियंत्रण संरचना रखते हैं, तो आप इस सूची का उपयोग ठीक-ठीक अनुकूलन प्राप्त करने के लिए कर सकते हैं। सूची यहां है: gcc.gnu.org/onbuildocs/gcc/Optimize-Options.html
केविन

7

मैंने यह प्रश्न जैक गैंसले को भेजा है और यही उन्होंने मुझे उत्तर दिया है:

डैनियल,

मैं जारी किए गए कोड में जो भी अनुकूलन होगा उसका उपयोग करके डिबग करना पसंद करता हूं। नासा का कहना है कि "आप क्या परीक्षण करते हैं, क्या आप परीक्षण करते हैं।" दूसरे शब्दों में, परीक्षण न करें और फिर कोड बदलें!

हालांकि, कभी-कभी किसी को अनुकूलन बंद करना पड़ता है ताकि डिबगर काम करेगा। मैं उन मॉड्यूलों को बंद करने की कोशिश करता हूं, जिन पर मैं काम कर रहा हूं। इस कारण से मुझे विश्वास है कि फाइलों को छोटा रखें, कोड की कुछ सौ पंक्तियों या तो कहें।

ऑल द बेस्ट, जैक


मुझे लगता है कि इस प्रतिक्रिया में दो पैराग्राफ के बीच एक अस्थिर अंतर है। परीक्षण से तात्पर्य एक ऐसी प्रक्रिया से है जो यह प्रदर्शित करती है कि नरम, दृढ़ और / या कठोर माल ठीक से काम करते हैं। डिबगिंग वह प्रक्रिया है जिसमें कोड को निर्देश-दर-निर्देश के माध्यम से यह देखने के लिए कदम रखा जाता है कि यह क्यों [अभी तक] काम नहीं कर रहा है।
केविन वर्मियर

चुनाव करना अच्छा है। इसलिए परीक्षण अनुकूलन के साथ और बिना अधिक किस्मों / क्रमपरिवर्तन को कवर कर सकता है। अधिक कवरेज, बेहतर परीक्षण है

@reemrevnivek, जब आप डिबगिंग कर रहे हैं, तो क्या आप भी परीक्षण नहीं कर रहे हैं?
डैनियल ग्रिलो

@ ओ इंगनेहिरो - नहीं। मैं केवल डिबग करता हूं यदि परीक्षण विफल हो जाता है।
केविन वर्मेयर

6

निर्भर करता है, और यह आम तौर पर C30 ही नहीं सभी उपकरणों का सच है।

अनुकूलन अक्सर विभिन्न तरीकों से कोड को हटाते हैं और / या पुनर्गठन करते हैं। आपके स्विच स्टेटमेंट को if / अन्यथा निर्माण के साथ फिर से लागू किया जा सकता है या कुछ मामलों में सभी को एक साथ हटाया जा सकता है। y = x * 16 को बाएं पारियों की एक श्रृंखला आदि के साथ बदल दिया जा सकता है, हालांकि इस अंतिम प्रकार के अनुकूलन को आमतौर पर अभी भी इसके माध्यम से आगे बढ़ाया जा सकता है, इसके नियंत्रण के बयान का पुनर्गठन जो हां हो जाता है।

यह आपके C कोड के माध्यम से डिबगर को ले जाने के लिए असंभव बना सकता है क्योंकि आपके द्वारा C में परिभाषित संरचनाएँ अब मौजूद नहीं हैं, उन्हें कंपाइलर द्वारा प्रतिस्थापित या फिर से आदेशित किया गया है जिससे कंपाइलर का मानना ​​है कि तेजी से होगा या कम स्थान का उपयोग करेगा। यह सी लिस्टिंग से ब्रेकपॉइंट को सेट करना असंभव बना सकता है क्योंकि आपके द्वारा दिए गए निर्देश का अब अस्तित्व नहीं रह सकता है। उदाहरण के लिए आप एक ifpoint के अंदर एक ब्रेकपॉइंट सेट करने का प्रयास कर सकते हैं, लेकिन कंपाइलर ने हटा दिया हो सकता है कि अगर। आप थोड़ी देर के लिए या लूप के लिए एक ब्रेकपॉइंट सेट करने का प्रयास कर सकते हैं, लेकिन संकलक ने उस लूप को अनियंत्रित करने का निर्णय लिया ताकि यह अब मौजूद न हो।

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

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

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


5

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

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


1
लेकिन एकल चरण को अनुकूलित करना चालू होने के साथ कोड को रोकना लगभग असंभव हो सकता है। ऑप्टिमाइज़ेशन के साथ डिबग करें, और रिलीज़ कोड के साथ अपनी इकाई परीक्षण चलाएं।
रॉकेटमेग्नेट

3

मेरी सामान्य रणनीति अंतिम अनुकूलन (आकार या गति के लिए अधिकतम) के साथ विकसित करना है, लेकिन अस्थायी रूप से अनुकूलन को फ्लिप करें यदि मुझे कुछ ट्रेस करने की आवश्यकता है ओटी ट्रेस। यह अनुकूलन स्तर बदलने के परिणामस्वरूप बग के खतरे को कम करता है।

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


2

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

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

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


1
+1 केवल अपने अच्छे उत्तर के बारे में विस्तार से बताएं: अक्सर "डिबग" मोड में संकलन करने से स्मॉलिश राइट-ऑफ-द-एंड और फॉर्मेट स्ट्रिंग त्रुटियों को कम करने के लिए गैर-आवंटित स्थान वाले वेरिएबल के आसपास स्टैक / हीप को पैड किया जाएगा। यदि आप रिलीज में संकलित करते हैं तो आपको अक्सर एक अच्छा रनटाइम क्रैश मिलेगा।
मोर्टन जेन्सेन

2

मैं हमेशा -O0 के साथ कोड विकसित करता हूं (अनुकूलन बंद करने के लिए जीसीसी विकल्प)। जब मुझे लगता है कि मैं उस बिंदु पर हूं, जहां मैं चीजों को एक रिलीज की ओर जाने देना शुरू करना चाहता हूं, तो मैं -ओवर (आकार के लिए अनुकूलन) के साथ शुरू करूंगा क्योंकि आमतौर पर जितना अधिक कोड आप कैश में रख सकते हैं उतना बेहतर होगा। भले ही यह सुपर-डुपर अनुकूलित नहीं है।

मुझे लगता है कि -d0 कोड के साथ gdb कहीं बेहतर काम करता है, और यदि आपको विधानसभा में कदम रखना है तो इसका पालन करना बहुत आसान है। -ओ 0 और -ओ के बीच टॉगल करने से भी आप देख सकते हैं कि आपके कोड में कंपाइलर क्या कर रहा है। यह कई बार एक दिलचस्प शिक्षा है, और संकलक कीड़ों को भी उजागर कर सकता है ... उन घिनौने काम जो आपको अपने बालों को खींचने की कोशिश कर रहे हैं, यह पता लगाने की कोशिश कर रहे हैं कि आपके कोड में क्या गलत है!

अगर मुझे वास्तव में इसकी आवश्यकता है, तो मैं -fdata-section और -fcode- वर्गों को --gc- अनुभागों के साथ जोड़ना शुरू करूँगा, जो लिंकर को पूरे फ़ंक्शन और डेटा खंडों को हटाने की अनुमति देते हैं जो वास्तव में उपयोग नहीं किए जाते हैं। बहुत सी छोटी चीजें हैं, जिनसे आप आगे की चीजों को सिकोड़ने या चीजों को तेज करने की कोशिश कर सकते हैं, लेकिन बड़े और ये एकमात्र ट्रिक्स हैं जिनका मैं उपयोग करता हूं, और कुछ भी जो छोटा या तेज होना चाहिए, मैं उसे हाथ लगाऊंगा। -assemble।


2

हां, डिबगिंग के दौरान अनुकूलन को अक्षम करना तीन कारणों से कुछ समय के लिए सबसे अच्छा अभ्यास रहा है:

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

बहुत से लोग इस दिशा में और भी आगे बढ़ जाते हैं, और दावे के साथ जहाज चला जाता है


असेंबली कोड के माध्यम से सिंगल-स्टेपिंग उन मामलों के निदान के लिए बहुत उपयोगी हो सकती है, जहां स्रोत कोड वास्तव में इसके अलावा कुछ और निर्दिष्ट करता है (जैसे "longvar1 & = ~ 0x40000000; longvar2 & = ~ 0x80000000;") और जहां एक कंपाइलर छोटी गाड़ी कोड बनाता है। । मैंने मशीन-कोड डीबगर्स का उपयोग करके कुछ समस्याओं को ट्रैक किया है जो मुझे नहीं लगता कि मैं किसी अन्य तरीके से ट्रैक कर सकता था।
सुपरकैट

2

सरल: अनुकूलन समय-गहन हैं, और बेकार हो सकते हैं यदि आपको विकास में बाद में उस कोड को बदलना होगा। इसलिए वे समय और धन की बर्बादी कर सकते हैं।
वे तैयार मॉड्यूल के लिए उपयोगी हैं, हालांकि; कोड के कुछ हिस्सों को जिन्हें शायद अब बदलाव की आवश्यकता नहीं होगी।


2

यह निश्चित रूप से ब्रेक पॉइंट्स के मामले में समझ में आता है ... क्योंकि संकलक बहुत सारे बयानों को हटा सकता है जो वास्तव में स्मृति को प्रभावित नहीं करते हैं।

कुछ इस तरह से विचार करें:

int i =0;

for (int j=0; j < 10; j++)
{
 i+=j;
}
return 0;

पूरी तरह से अनुकूलित किया जा सकता है (क्योंकि iकभी पढ़ा नहीं है)। यह आपके ब्रेकपॉइंट के दृष्टिकोण से देखेगा कि यह उस सभी कोड को छोड़ देता है, जब यह मूल रूप से अभी भी नहीं था .... मुझे लगता है कि नींद के प्रकार के कार्यों में आप अक्सर कुछ ऐसा देखेंगे:

for (int j=delay; j != 0; j--)
{
    asm( " nop " );
    asm( " nop " );
}
return 0;

1

यदि आप डिबगर का उपयोग कर रहे हैं तो मैं ऑप्टिमाइज़ेशन अक्षम कर दूंगा और डीबग सक्षम करूंगा।

व्यक्तिगत रूप से मुझे लगता है कि PIC डिबगर की वजह से अधिक समस्याएं होती हैं जो मुझे ठीक करने में मदद करती है।
मैं सिर्फ C18 में लिखे गए अपने कार्यक्रमों को डिबग करने के लिए प्रिंट () का उपयोग USART के लिए करता हूं।


1

आपके संकलन में अनुकूलन को सक्षम करने के खिलाफ अधिकांश तर्क निम्न हैं:

  1. डिबगिंग के साथ परेशानी (JTAG कनेक्टिविटी, ब्रेकप्वाइंट आदि)
  2. गलत सॉफ्टवेयर टाइमिंग
  3. sh * t सही ढंग से काम करना बंद कर देता है

IMHO पहले दो वैध हैं, तीसरा इतना नहीं। अक्सर इसका मतलब है कि आपके पास कुछ बुरा कोड है या भाषा / कार्यान्वयन के असुरक्षित शोषण पर भरोसा कर रहे हैं या शायद लेखक सिर्फ अच्छे राजभाषा 'अंकल अनफाइंड बिहेवियर के प्रशंसक हैं।

अकादमिक ब्लॉग में एंबेडेड को अपरिभाषित व्यवहार के बारे में कहने के लिए एक या दो बातें हैं, और यह पोस्ट इस बात पर है कि कंपाइलर इसका कैसे फायदा उठाते हैं: http://blog.regehr.org/archives/761


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