2009-03-19 11 views
11

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

+0

मुझे लगता है कि प्रश्न "कोड आकार" के बजाय "स्मृति उपयोग" या "आउटपुट आकार" कहना चाहिए। – Angel

+0

मेमोरी उपयोग समस्या नहीं है। यह छवि का आकार है जो एमसीयू की आंतरिक फ्लैश मेमोरी में लिखा गया है। –

+0

मुझे लगता है कि "संकलित कोड का आकार" कम अस्पष्ट है। –

उत्तर

17
  • उपयोग पीढ़ी जहां संभव
  • इनलाइन कार्यों अक्षम
  • बारी डेटा तालिका के बजाय कार्यों अक्सर कार्यों में इस्तेमाल किया मैक्रो
  • देशी की मशीन आकार से बड़े चर के लिए संकल्प को कम (यानी, 8 बिट माइक्रो, 16 और 32 बिट चर से छुटकारा पाने का प्रयास करें - युगल और कुछ कोड अनुक्रमों को चौगुनी करें)
  • यदि माइक्रो के पास एक छोटा निर्देश सेट (आर्म थंब) है तो इसे कंपाइलर
  • में सक्षम करें यदि ज्ञापन ory खंडित किया है (यानी, पृष्ठांकित या nonlinear) तो
    • पुनर्व्यवस्थित करें कोड ताकि कम वैश्विक कॉल (बड़ा कॉल निर्देश) वैश्विक स्मृति को खत्म करने
    • पुनर्व्यवस्थित करें कोड और चर उपयोग प्रयोग की जाने वाली कॉल
    • पुनः की जरूरत है वैश्विक स्मृति के उपयोग का मूल्यांकन - अगर यह तो ढेर पर रखा जा सकता इतना बेहतर
  • वाकई डीबग साथ संकलित कर रहे हैं बंद कर दिया है - कुछ प्रोसेसर पर यह एक बड़ा अंतर
  • कम्प्रेस डेटा जो कर सकते हैं बनाता है ओ उत्पन्न नहीं किया जाएगा एन फ्लाई - फिर तेजी से पहुंच
  • कंपाइलर विकल्पों में डेल करें - यह हो सकता है कि प्रत्येक कॉल स्वचालित रूप से वैश्विक हो, लेकिन आप आकार को कम करने के लिए फाइल के आधार पर फ़ाइल पर सुरक्षित रूप से अक्षम कर पाएंगे (कभी कभी काफी)

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

मिसाल के तौर पर, आप हो सकता है कई 'अगर' बयान है कि ऐसी तुलनाएं कर:

if(A && B && (C || D)){} 
if(A && !B && (C || D)){} 
if(!A && B && (C || D)){} 

तब चर नए सिरे से बनाने और डुप्लिकेट कोड से संकलक की बचत होगी अग्रिम में कुछ तुलना करने:

E = (C || D); 

if(A && B && E){} 
if(A && !B && E){} 
if(!A && B && E){} 

यह ऑप्टिमाइज़ेशन में से एक है जब संकलक स्वचालित रूप से आपके लिए चालू करता है तो आप इसे चालू करते हैं। कई, कई अन्य हैं, और यदि आप सी कोड में हाथ से ऐसा करना सीखना चाहते हैं तो आप थोड़ा संकलक सिद्धांत पढ़ना चाहेंगे।

+1

एकमात्र चेतावनी यह होगी कि समय-महत्वपूर्ण अनुभागों में से कोई भी प्रक्रिया अतिरिक्त परीक्षण की गारंटी देगी। –

+0

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

+0

यदि आप इनलाइन फ़ंक्शंस को अक्षम करते हैं, और मैक्रोज़ को फ़ंक्शंस में बदलते हैं, तो आप रनटाइम मेमोरी उपयोग (अधिक फ़ंक्शन कॉल = नए स्टैकफ्रेम) को नहीं बढ़ा रहे हैं। हालांकि मैं इस सामान के बारे में निश्चित नहीं हूँ। – DevinB

2

duplicate code को रिफैक्टरिंग आपके प्रोग्राम की मेमोरी पदचिह्न पर सबसे बड़ा प्रभाव होना चाहिए।

0

मैक्रोज़ पर ध्यान दें। वे सिर्फ एक मैक्रो विस्तार से बहुत सारे कोड का उत्पादन कर सकते हैं। यदि आपको ऐसे मैक्रोज़ मिलते हैं - उन्हें फिर से लिखने का प्रयास करें ताकि उनका आकार कम हो और कार्यक्षमता फ़ंक्शंस में ले जाया जा सके।

डुप्लिकेट कोड पर ध्यान दें - कॉपी-पेस्ट और तार्किक रूप से डुप्लिकेट दोनों। कार्यों में डुप्लिकेट कोड को अलग करने का प्रयास करें।

जांचें कि संकलक इनलाइनिंग का समर्थन करता है या इसे बंद कर दिया जा सकता है।

0

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

यह पठनीयता पर आकार का पक्ष ले रहा है, इसलिए कभी-कभी गेटोस के साथ बहुत बदसूरत हो जाता है।

+1

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

7

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

कुछ पर्ल या पसंद के साथ, आप एक .xMAP फ़ाइल का संक्षिप्त काम या "objdump" या "nm" के परिणाम बना सकते हैं, और प्रासंगिक जानकारी के लिए इसे विभिन्न तरीकों से फिर से क्रमबद्ध कर सकते हैं।


छोटे निर्देश सेट करने के लिए विशिष्ट: literal pool उपयोग के लिए देखें। उदाहरण से बदलते समय एआरएम (प्रति निर्देश 32 बिट) निर्देश THUMB (16 बिट्स प्रति निर्देश) निर्देश सेट पर सेट कुछ एआरएम प्रोसेसर पर उपयोगी हो सकता है, यह "तत्काल" फ़ील्ड के आकार को कम कर देता है।

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

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

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


अन्यथा: स्थैतिक संरचनाओं और गैर-तुच्छ-निर्मित डेटा के सरणी के लिए नजर रखें। इनमें से प्रत्येक आम तौर पर बड़ी मात्रा में .initit कोड ("अदृश्य फ़ंक्शन", यदि आप करेंगे) उत्पन्न करता है जो मुख्य() से पहले इन arrays को ठीक से पॉप्युलेट करने के लिए चलाया जाता है। यदि आप अपनी स्टेटिक्स में केवल छोटे डेटा प्रकारों का उपयोग कर सकते हैं, तो आप बहुत बेहतर होंगे।

यह फिर से कुछ है जिसे आसानी से "एनएम" या "ओब्जडम्प" या इसी तरह के परिणामों पर एक उपकरण का उपयोग करके पहचाना जा सकता है। यदि आपके पास .init सामान का एक टन है, तो आप जांच करना चाहेंगे!


ओह, और - अपने संकलक/लिंकर यह समर्थन करता है तो, चुनिंदा बस कुछ फ़ाइलों या कार्यों के लिए अनुकूलन या छोटे निर्देश सेट सक्षम करने के लिए डर नहीं है!

+0

+1 एक अच्छा रबर-मिल-द-रोड दृष्टिकोण। –

+0

+1 लिंकर मानचित्र फ़ाइल शुरू करने की जगह है। यह आपको दिखाएगा कि अंतरिक्ष कहां इस्तेमाल किया जा रहा है। –

0

उपरोक्त उत्तरों का दावा है "कंपाइलर अनुकूलन चालू करना [कोड आकार को कम करना]"।सभी दस्तावेज और अनुभव को देखते हुए मैंने एम्बेडेड सिस्टम टीआई डीएसपी प्रोग्रामिंग में पाया है, मुझे पता है कि ऑप्टिमाइज़ेशन चालू करने से आपका कोड आकार बढ़ जाएगा (टीआई डीएसपी चिप के लिए)!


मुझे स्पष्ट करने दें:

TI TMSCx6416 डीएसपी 9 संकलक झंडे कि अपने कोड आकार को प्रभावित करेगा है। अनुकूलन के लिए

  1. 3 अलग अलग झंडे
  2. 3 डिबगिंग
  3. कोड आकार

मेरी संकलक लिए, जब आप अनुकूलन स्तर तीन प्रलेखन राज्यों पर बारी के लिए

  • 3 अलग झंडे के लिए अलग अलग झंडे:

    1. कुछ फ़ंक्शंस के लिए ऑटो-इनलाइनिंग घटित होगी -> कोड आकार
    2. 012 बढ़ाएगा
    3. सॉफ्टवेयर पाइपलाइनिंग सक्षम है -> कोड आकार

    सॉफ़्टवेयर पाइपलाइनिंग क्या है?

    वह जगह है जहां संकलक असेंबली में चीजें करेगा जो लूप को काफी तेजी से निष्पादित करता है (दो गुना तेजी से) लेकिन अधिक कोड आकार की लागत पर। मैं software pipelining at wikipedia के बारे में पढ़ने का सुझाव देता हूं (लूप अनोलिंग, प्रोलॉग और एपिलॉग के लिए देखो)।

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


    एक और सुझाव संकलक झंडे कि कोड आकार से संबंधित हैं देखने के लिए है। यदि आपके पास कोड आकार कंपाइलर झंडे हैं, तो उन्हें उच्चतम सेटिंग तक क्रैंक करना सुनिश्चित करें। आम तौर पर कोड आकार के लिए संकलन का मतलब है कि आपका कोड धीमा निष्पादित करेगा ... लेकिन आपको ऐसा करना पड़ सकता है।

  • +0

    टीआई एमएसपी 430 लक्ष्य के लिए आईएआर ईडब्ल्यू 430 के आकार के लिए उच्च स्तरीय अनुकूलन का उपयोग संकलित कोड आकार को कम करता है, लेकिन यह वह समाधान नहीं है जिसे मैंने चुना है। –

    +0

    विकल्प उत्पन्न करने वाले कंपाइलर झंडे को देखते हुए, इनलाइनिंग और लूप अनोलिंग अक्षम करना उनमें से हैं। वे कार्य वर्तमान उत्तरों में पहले ही उल्लेख किए गए हैं। –

    +0

    आपकी समस्या की तरह लगता है पहले से ही हल हो गया है। अपनी जिज्ञासा के लिए, ऑप्टिमाइज़ेशन पर मोड़ने वाले आपके कंपाइलर में इनलाइन/लूप अनोलिंग/आदि अक्षम करने के परिणामस्वरूप? –

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

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