अधिक फ्लैश और रैम के लिए कोड को कैसे निचोड़ें? [बन्द है]


14

मैंने हमारे एक विशेष उत्पाद पर एक विशेषता विकसित करने पर काम किया है। उसी सुविधा को किसी अन्य उत्पाद में पोर्ट करने का अनुरोध किया गया है। यह उत्पाद M16C माइक्रोकंट्रोलर पर आधारित है, जिसमें पारंपरिक रूप से 64K फ्लैश और 2k RAM है।

यह एक परिपक्व उत्पाद है, और इसलिए, केवल 132 बाइट्स फ्लैश और 2 बाइट्स रैम बचे हैं।

अनुरोध की गई सुविधा को पोर्ट करने के लिए (फीचर को स्वयं ऑप्टिमाइज़ किया गया है), मुझे 1400 बाइट्स की जरूरत है और ~ 200 बाइट्स रैम की।

क्या किसी के पास कोई सुझाव है कि इन बाइट्स को कोड कंपटीशन द्वारा कैसे पुनः प्राप्त किया जाए? जब मैं पहले से ही काम कर रहे कोड को कॉम्पैक्ट करने की कोशिश कर रहा हूं, तो मुझे किन विशिष्ट चीजों की तलाश है?

किसी भी विचार वास्तव में सराहना की जाएगी।

धन्यवाद।


1
सुझावों के लिए सभी को धन्यवाद। मैं आपको अपनी प्रगति के साथ अद्यतन रखूंगा और उन चरणों को सूचीबद्ध करूंगा, जो काम किया है, और जो नहीं किया है।
IntelliChick

ठीक है, यहाँ मैं कोशिश की है कि काम कर रहे हैं: संकलक संस्करणों को स्थानांतरित कर दिया। अनुकूलन में काफी सुधार हुआ था जिसने मुझे लगभग 2k का Flash दिया था। विशेष उत्पाद के लिए निरर्थक और अप्रयुक्त कार्यक्षमता (सामान्य कोड आधार के कारण विरासत में मिली) की जाँच करने के लिए सूची फ़ाइलों के माध्यम से चला गया और कुछ और फ़्लैश प्राप्त की।
IntelliChick

रैम के लिए मैंने निम्नलिखित कार्य किया: मैप फ़ाइल के माध्यम से, उन कार्यों / मॉड्यूल की जांच करने के लिए गया जो सबसे अधिक रैम का उपयोग कर रहे थे। मुझे एक वास्तव में भारी कार्य (12 चैनल, प्रत्येक आवंटित मेमोरी की एक निश्चित राशि के साथ), विरासत कोड की समझ में आया कि यह क्या हासिल करने की कोशिश कर रहा था, और उन चैनलों के बीच जानकारी साझा करके, रैम उपयोग को अनुकूलित किया जो सामान्य था। इससे मुझे ~ 200 बाइट्स की जरूरत पड़ी।
IntelliChick

यदि आपके पास एससीआई फाइलें हैं तो आप 8 से 7 बिट संपीड़न का उपयोग कर सकते हैं। आपको 12.5% ​​बचाता है। एक ज़िप फ़ाइल का उपयोग करने के लिए ज़िप और संयुक्त राष्ट्र ज़िप यह करने के लिए की तुलना में अधिक कोड ले जाएगा।
Sparky256

जवाबों:


18

आपके पास कुछ विकल्प हैं: पहला यह है कि निरर्थक कोड की तलाश करें और दोहराव से छुटकारा पाने के लिए इसे एकल कॉल में स्थानांतरित करें; दूसरी कार्यक्षमता निकालना है।

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

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

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


1
सुझावों के लिए धन्यवाद, मैं निश्चित रूप से उनमें से अधिकांश का प्रयास कर सकता हूं, सिवाय स्ट्रिंग स्थिरांक के लिए। यह विशुद्ध रूप से एक एम्बेडेड डिवाइस है, जिसमें कोई UI नहीं है और इसलिए कोड के भीतर प्रिंटफ () के लिए कोई कॉल नहीं है। उम्मीद है कि उन सुझावों को मुझे अपनी 1400 बाइट्स फ्लैश / 200 बाइट्स रैम के लिए प्राप्त करना चाहिए जो मुझे चाहिए।
IntelliChick

1
@IntelliChick आप चकित होंगे कि कितने लोग प्रिंट करने के लिए एम्बेडेड डिवाइस के अंदर प्रिंटफ () का उपयोग करते हैं या तो डिबगिंग के लिए प्रिंट करते हैं या किसी परिधीय को भेजते हैं। ऐसा लगता है कि आप इसे बेहतर जानते हैं, लेकिन अगर किसी ने आपके सामने परियोजना पर कोड लिखा है, तो इसके लिए जाँच करने के लिए दुख नहीं होगा।
कालेनजब 5

5
और सिर्फ मेरी पिछली टिप्पणी पर विस्तार करने के लिए, आप भी चकित होंगे कि कितने लोग डिबगिंग स्टेटमेंट जोड़ते हैं, लेकिन उन्हें कभी नहीं हटाते हैं। यहां तक ​​कि जो लोग #ifdefs करते हैं वे अभी भी आलसी हो जाते हैं।
कालेनजब 5

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

बस इस पर एक सवाल - क्या नेस्टेड फ़ंक्शन कॉल के बारे में परत से परत तक। कितना उपरि जोड़ता है? क्या कई फ़ंक्शन कॉल करने या फ़ंक्शन कॉल को कम करने और कुछ बाइट्स को बचाकर मॉड्यूलरिटी रखना बेहतर है। और क्या यह महत्वपूर्ण है?
IntelliChick 5

8

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

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

या सरणी अनुक्रमण बहुत महंगा हो सकता है लेकिन सूचक संचालन बहुत सस्ता है। या ठीक इसके विपरीत।

लेकिन विधानसभा भाषा को देखना पहला कदम है।


3
यह बहुत महत्वपूर्ण है कि आप जानते हैं कि आपका कंपाइलर क्या करता है। आपको देखना चाहिए कि मेरे कंपाइलर में क्या विभाजन है। यह शिशुओं को रोता है (स्वयं शामिल है)।
कोर्तुक

8

उदाहरण के लिए, कंपाइलर अनुकूलन, -Osजीसीसी में गति और कोड आकार के बीच सबसे अच्छा संतुलन देता है। बचें -O3, क्योंकि इससे कोड का आकार बढ़ सकता है।


3
यदि आप ऐसा करते हैं, तो आपको हर जगह पुन: प्रयास करना होगा! ऑप्टिमाइज़ेशन कार्य कोड का कारण बन सकता है क्योंकि नई मान्यताओं के कारण कंपाइलर काम नहीं करता है।
रॉबर्ट

@ रॉबर्ट, यदि आप अपरिभाषित कथनों का उपयोग करते हैं तो यह सच है: जैसे a = a ++ अलग-अलग तरीके से -O0 और -O3 संकलित करेगा।
थॉमस ओ

5
@ थोमस सच नहीं है। यदि आपके पास घड़ी चक्रों में देरी करने के लिए एक लूप है, तो कई ऑप्टिमाइज़र आपको महसूस करेंगे कि इसमें कुछ भी नहीं किया गया है और इसे हटा दें। यह सिर्फ 1 उदाहरण है।
केलनजेब

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

1
सभी अच्छे अंक। परिभाषा के अनुसार अस्थिर कार्य / चर, अनुकूलित नहीं होने चाहिए। कोई भी आशावादी जो इस तरह (कॉल-टाइम और इनलाइनिंग सहित) पर अनुकूलन करता है, टूट जाता है।
थॉमस ओ

8

RAM के लिए, अपने सभी चरों की श्रेणी की जाँच करें - क्या आप उन इन्ट्स का उपयोग कर रहे हैं जहाँ आप एक चार का उपयोग कर सकते हैं? क्या बफ़र्स उनसे बड़े होने की ज़रूरत है?

कोड निचोड़ बहुत ही आवेदन और कोडिंग शैली पर निर्भर है। आपके द्वारा छोड़ी गई राशियाँ बताती हैं कि हो सकता है कि कुछ निचोड़ने के लिए कोड पहले ही जा चुका हो, जिसका अर्थ यह हो सकता है कि होना बाकी है।

समग्र कार्यक्षमता पर भी एक कड़ी नज़र डालें - क्या ऐसा कुछ है जो वास्तव में उपयोग नहीं किया गया है और इसे जेल किया जा सकता है?


8

यदि यह एक पुरानी परियोजना है, लेकिन संकलक को विकसित किया गया है, तो यह हो सकता है कि अधिक हालिया संकलक छोटे कोड का उत्पादन कर सकता है


धन्यवाद माइक! मैंने अतीत में यह कोशिश की है, और प्राप्त स्थान पहले ही उपयोग किया जा चुका है! :) IAR C कंपाइलर 3.21d से 3.40 पर ले जाया गया।
IntelliChick

1
मैं एक और संस्करण ले आया, और फीचर को फिट करने के लिए कुछ और फ्लैश प्राप्त करने में कामयाब रहा। मैं वास्तव में रैम के साथ संघर्ष कर रहा हूं, हालांकि यह अपरिवर्तित रहा है। :(
IntelliChick

7

यह हमेशा स्थान का अनुकूलन करने के विकल्पों के लिए अपने संकलक मैनुअल की जाँच करने के लायक है।

जीसीसी के लिए -ffunction-sectionsऔर लिंकर ध्वज के -fdata-sectionsसाथ --gc-sectionsमृत कोड को अलग करने के लिए अच्छे हैं।

यहाँ कुछ अन्य उत्कृष्ट सुझाव दिए गए हैं (AVR की ओर)


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

मेरा अनुभव है कि यह AVR
Toby Jaffey

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

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

6

आप स्टैक स्पेस और हीप स्पेस की मात्रा की जांच कर सकते हैं जो आवंटित किए गए हैं। यदि आप या तो इन दोनों को अधिक मात्रा में आवंटित किए गए हैं, तो आप पर्याप्त मात्रा में रैम वापस पा सकते हैं।

मेरा अनुमान है (के उपयोग के एक परियोजना है कि राम की 2k में फिट बैठता है शुरू करने के लिए के साथ इसमें कोई गतिशील स्मृति आवंटन है के लिए है malloc, callocआदि)। यदि यह मामला है तो आप पूरी तरह से आप से छुटकारा पा सकते हैं मूल लेखक को यह मानते हुए कि कुछ राम ने ढेर के लिए आवंटित किया है।

आपको स्टैक आकार को कम करने के लिए बहुत सावधान रहना होगा क्योंकि इससे कीड़े पैदा हो सकते हैं जिन्हें ढूंढना बहुत मुश्किल है। किसी ज्ञात मान (पूरे मान 0x00 या 0xff के अलावा कुछ और के रूप में इन स्टैक स्थान को प्रारंभ करने से प्रारंभ करने के लिए सहायक हो सकता है क्योंकि ये मान आमतौर पर पहले से ही मौजूद हैं) तो सिस्टम को थोड़ी देर के लिए देखें कि स्टैक स्थान अप्रयुक्त कैसे है।


ये बहुत अच्छे विकल्प हैं। मैं ध्यान देता हूं कि आपको कभी भी एम्बेडेड सिस्टम में मॉलोक का उपयोग नहीं करना चाहिए।
कोर्तुक

1
@Kortuk एम्बेडेड की अपनी परिभाषा पर निर्भर करता है और कार्य किया जा रहा है
टोबी जाफ़े

1
@joby, हाँ, मैं समझता हूँ कि। 0 रीस्टार्ट वाले सिस्टम में और लिनक्स जैसे OS की अनुपस्थिति में, मॉलोक बहुत खराब हो सकता है।
कोर्तुक

कोई डायनामिक मेमोरी एलोकेशन नहीं है, कोई भी जगह जहां मॉलोक, कॉलोक का उपयोग नहीं किया जा रहा है। मैंने ढेर आवंटन की भी जाँच की है, और इसे पहले से ही 0 पर सेट किया गया है, इसलिए ढेर आवंटन नहीं है। वर्तमान में आवंटित स्टैक आकार 254 बाइट्स और 128 बाइट्स में स्टैक स्टैक आकार है।
IntelliChick

5

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

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

क्या आपके कोड में बड़ी मात्रा में निरंतर डेटा है, जैसे कि स्ट्रिंग टेबल, HTML पेज या पिक्सेल ग्राफिक्स (आइकन)? यदि यह पर्याप्त रूप से बड़ा है (10 kB कहो), यह डेटा को सिकोड़ने और जरूरत पड़ने पर इसे उड़ने के लिए कम करने के लिए एक बहुत ही सरल संपीड़न योजना को लागू करने के लायक हो सकता है।


2 छोटे लुकअप टेबल हैं, जिनमें से कोई भी दुर्भाग्य से 10K तक नहीं होगा। और कोई भी फ्लोटिंग पॉइंट मैथ्स का उपयोग नहीं किया जा रहा है। :( यद्यपि सुझाव के लिए धन्यवाद। वे अच्छे हैं।
IntelliChick

2

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

यहाँ M16C के लिए फोर्थ है


2

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


1
वर्तमान में आकार के लिए अधिकतम के लिए अनुकूलित। :) फिर भी सुझाव के लिए धन्यवाद। :)
IntelliChick

2

यदि आप पहले से ही IAR जैसे पेशेवर-स्तरीय संकलक का उपयोग कर रहे हैं, तो मुझे लगता है कि आप मामूली निम्न-स्तरीय कोड-ट्विकिंग द्वारा किसी भी गंभीर बचत को प्राप्त करने के लिए संघर्ष करने जा रहे हैं - आपको कार्यक्षमता को हटाने या प्रमुख करने की दिशा में अधिक देखने की आवश्यकता होगी एक अधिक कुशल तरीके से भागों का पुनर्लेखन। आपको मूल कोड लिखने वाले से अधिक चालाक कोडर होने की आवश्यकता होगी ... RAM के रूप में आपको वर्तमान में इसका उपयोग कैसे किया जाता है, इस पर बहुत ही कठोर नज़र डालने की आवश्यकता है, और देखें कि क्या उसी RAM के ओवरलेइंग उपयोग की गुंजाइश है अलग-अलग समय पर अलग-अलग चीजें (इसके लिए यूनियनें आसान हैं)। एआरएम / एवीआर वालों में IAR के डिफॉल्ट हीप और स्टैक साइज को मैंने ज्यादा उदार बनाया है, इसलिए ये पहली चीज होगी।


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

मुझे कैसे पता चलेगा कि स्टैक आकार का आकार क्या उचित है?
IntelliChick

2

जांच करने के लिए कुछ और - कुछ आर्किटेक्चर पर कुछ कंपाइलर रैम में स्थिरांक की प्रतिलिपि बनाते हैं - आमतौर पर तब उपयोग किया जाता है जब फ्लैश स्थिरांक तक पहुंच धीमी / कठिन होती है (उदाहरण के लिए AVR) जैसे IAR के AVR कंपाइलर को RAM की निरंतर प्रतिलिपि नहीं बनाने के लिए _ _flash क्वालिफायर की आवश्यकता होती है )


धन्यवाद माइक। हाँ, मैंने पहले ही जाँच कर ली थी कि - इसे M16C IAR C कंपाइलर के लिए 'राइट करने योग्य स्थिरांक' विकल्प कहा जाता है। यह ROM से RAM तक स्थिरांक की प्रतिलिपि बनाता है। यह विकल्प मेरी परियोजना के लिए अनियंत्रित है। लेकिन वास्तव में वैध जाँच! धन्यवाद।
IntelliChick

1

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

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

एआरएम पर, वैश्विक चर डालते हैं जो अक्सर एक संरचना में एक साथ उपयोग किए जाते हैं, कोड आकार को कम कर सकते हैं और प्रदर्शन में सुधार कर सकते हैं। यदि A, B, C, D, और E अलग-अलग वैश्विक चर हैं, तो उन सभी का उपयोग करने वाले कोड को प्रत्येक के पते को एक रजिस्टर में लोड करना होगा; यदि पर्याप्त रजिस्टर नहीं हैं, तो कई बार उन पते को फिर से लोड करना आवश्यक हो सकता है। इसके विपरीत, यदि वे एक ही वैश्विक संरचना MyStuff का हिस्सा हैं, तो कोड जो MyStuff.A, MyStuff.B आदि का उपयोग करता है, बस एक बार MyStuff के पते को लोड कर सकता है। बड़ी जीत।


1

1. यदि आपका कोड बहुत सारी संरचनाओं पर निर्भर करता है, तो सुनिश्चित करें कि संरचना सदस्यों को उन लोगों से आदेश दिया जाता है जो कम से कम सबसे अधिक मेमोरी पर कब्जा करते हैं।

Ex: "uint16_t uint8_t uint32_t" के बजाय "uint32_t uint16_t uint8_t"

यह न्यूनतम संरचना पैडिंग सुनिश्चित करेगा।

जहां लागू हो चर के लिए 2.Use कास्ट करें। यह सुनिश्चित करेगा कि वे चर रोम में होंगे और रैम को नहीं खाएंगे


1

कुछ (शायद स्पष्ट) ट्रिक्स मैंने कुछ ग्राहक के कोड को संपीड़ित करने में सफलतापूर्वक उपयोग की हैं:

  1. बिट फ़ील्ड्स या बिट मास्क में कॉम्पैक्ट झंडे। यह फायदेमंद हो सकता है क्योंकि आम तौर पर बूलियन को पूर्णांकों के रूप में संग्रहीत किया जाता है और इस प्रकार मेमोरी बर्बाद होती है। यह रैम और रोम दोनों को बचाएगा और आमतौर पर कंपाइलर द्वारा नहीं किया जाता है।

  2. कोड में अतिरेक के लिए देखें, और दोहराया बयानों को निष्पादित करने के लिए छोरों या कार्यों का उपयोग करें।

  3. मैंने if(x==enum_entry) <assignment>अनुक्रमित सरणी के साथ स्थिरांक के कई बयानों को प्रतिस्थापित करके कुछ ROM को बचाया है , इस बात का ध्यान रखते हुए कि एनुम प्रविष्टियों का उपयोग सरणी सूचकांक के रूप में किया जा सकता है


0

यदि आप कर सकते हैं, तो इनलाइन फ़ंक्शन या कंपाइलर मैक्रोज़ का उपयोग छोटे कार्यों के बजाय करें। गुजरती तर्कों के साथ आकार और गति ओवरहेड है और फ़ंक्शन को इनलाइन बनाकर इसे सुधारा जा सकता है।


1
किसी भी सभ्य संकलक को कवक के लिए यह स्वचालित रूप से करना चाहिए जिसे केवल एक बार कहा जाता है।
मिसेइलेक्ट्रिकस्टफ

5
मैंने पाया है कि इनलाइनिंग आमतौर पर गति अनुकूलन के लिए अधिक उपयोगी होती है, और आमतौर पर बढ़े हुए आकार की कीमत पर।
क्रेग मैकक्वीन

inlining आम तौर पर कोड आकार में वृद्धि करेगा, जैसे कि तुच्छ कार्यों के अलावाint get_a(struct x) {return x.a;}
दिमित्री ग्रिगोरीव

0

अपने चर रजिस्टर के समान आकार के लिए स्थानीय चर बदलें।

यदि सीपीयू 32-बिट है, तो 32-बिट चर का उपयोग करें, भले ही अधिकतम मूल्य 255 से ऊपर कभी नहीं मिलेगा। मैंने 8-बिट चर का उपयोग किया है, कंपाइलर ऊपरी 24 बिट्स को बंद करने के लिए कोड जोड़ देगा।

पहली जगह जो मैं देखूंगा वह है लूप वेरिएबल्स के लिए।

for( i = 0; i < 100; i++ )

यह 8-बिट चर के लिए एक अच्छी जगह की तरह लग सकता है, लेकिन 32-बिट चर कम कोड का उत्पादन कर सकता है।


यह कोड बचा सकता है लेकिन यह रैम खाएगा।
मिसेइलेक्ट्रिकस्टफ

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

2
आमतौर पर यह सच है कि यह एक स्थानीय चर है। रैम पर कम होने पर, वैश्विक संस्करण, विशेष रूप से सरणियों का आकार, बचत की तलाश शुरू करने के लिए एक अच्छी जगह है।
mikeselectricstuff

1
एक और संभावना, दिलचस्प है, हस्ताक्षरित के साथ अहस्ताक्षरित चर को प्रतिस्थापित करना। यदि कोई कंपाइलर 32-बिट रजिस्टर के लिए अहस्ताक्षरित शॉर्ट को अनुकूलित करता है, तो उसे यह सुनिश्चित करने के लिए कोड जोड़ना होगा कि उसका मान 65535 से शून्य तक हो। यदि, हालांकि, संकलक एक रजिस्टर में हस्ताक्षरित शॉर्ट का अनुकूलन करता है, तो इस तरह के कोड की आवश्यकता नहीं है। क्योंकि इस बात की कोई गारंटी नहीं है कि अगर 32767 से कम वेतन वृद्धि होती है, तो उससे निपटने के लिए कोड का उत्सर्जन करने की आवश्यकता नहीं है। कम से कम दो एआरएम संकलक मैंने देखे हैं, उस कारण से हस्ताक्षरित-लघु कोड अहस्ताक्षरित-लघु कोड से छोटा हो सकता है।
सुपरकैट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.