@ vicatcu का उत्तर बहुत व्यापक है। ध्यान देने वाली एक अतिरिक्त बात यह है कि CPU I / O तक पहुँचने पर प्रतीक्षा अवस्थाओं (रुके हुए सीपीयू चक्र) में चला सकता है, जिसमें प्रोग्राम और डेटा मेमोरी शामिल है।
उदाहरण के लिए, हम TI F28335 DSP का उपयोग कर रहे हैं; RAM के कुछ क्षेत्र प्रोग्राम और डेटा मेमोरी के लिए 0-प्रतीक्षा स्थिति हैं, इसलिए जब आप RAM में कोड निष्पादित करते हैं, तो यह 1 चक्र प्रति निर्देश पर चलता है (उन निर्देशों को छोड़कर जो 1 से अधिक चक्र लेते हैं)। जब आप FLASH मेमोरी (बिल्ट-इन EEPROM, कम या ज्यादा) से कोड निष्पादित करते हैं, हालांकि, यह पूर्ण 150MHz पर नहीं चल सकता है और यह कई बार धीमा है।
हाई-स्पीड इंटरप्ट कोड के संबंध में, आपको कई चीजें सीखनी चाहिए।
सबसे पहले, अपने संकलक के साथ बहुत परिचित हो जाएं। यदि कंपाइलर एक अच्छा काम करता है, तो यह ज्यादातर चीजों के लिए हाथ से कोडित विधानसभा की तुलना में बहुत धीमा नहीं होना चाहिए। (जहां "इतना धीमा": 2 का एक कारक मेरे द्वारा ठीक होगा; 10 का एक कारक अस्वीकार्य होगा) आपको कंपाइलर ऑप्टिमाइज़ेशन फ़्लैग का उपयोग करने के लिए (और कब) सीखने की ज़रूरत है, और हर एक बार आपको देखना चाहिए संकलक के आउटपुट पर यह देखने के लिए कि यह कैसे करता है।
कंपाइलर को स्पीडअप करने के लिए आपके पास कुछ अन्य चीजें हो सकती हैं:
इनलाइन फ़ंक्शंस का उपयोग करें (यह याद नहीं कर सकता कि C यह समर्थन करता है या यदि यह केवल C ++ - ism है), दोनों छोटे फ़ंक्शंस के लिए और फ़ंक्शंस के लिए जो केवल एक या दो बार निष्पादित होने जा रहे हैं। नकारात्मक पक्ष यह है कि इनलाइन फ़ंक्शन डीबग करना कठिन हैं, खासकर यदि कंपाइलर ऑप्टिमाइज़ेशन चालू हो। लेकिन वे आपको अनावश्यक कॉल / रिटर्न क्रम बचाते हैं, खासकर यदि कोड फ़ंक्शन के बजाय "फ़ंक्शन" अमूर्त वैचारिक डिजाइन उद्देश्यों के लिए है।
अपने कंपाइलर के मैनुअल को देखें कि क्या उसमें आंतरिक कार्य हैं - ये कंपाइलर-डिपेंडेंट बिल्टिन फ़ंक्शंस हैं जो सीधे प्रोसेसर के असेंबली निर्देशों पर मैप करते हैं; कुछ प्रोसेसरों में असेंबली निर्देश होते हैं जो मिन / मैक्स / बिट रिवर्स जैसी उपयोगी चीजें करते हैं और आप ऐसा करने में समय बचा सकते हैं।
यदि आप संख्यात्मक अभिकलन कर रहे हैं, तो सुनिश्चित करें कि आप गणित-पुस्तकालय कार्यों को अनावश्यक रूप से नहीं कह रहे हैं। हमारे पास एक मामला था जहां कोड y = (y+1) % 4
एक काउंटर के लिए कुछ ऐसा था जिसमें 4 की अवधि थी, जिससे कंपाइलर को मॉडुलो 4 को एक बिटवाइज़-एंड के रूप में लागू करने की उम्मीद थी। इसके बजाय इसे गणित पुस्तकालय कहा जाता है। इसलिए हमने वह कर दिया y = (y+1) & 3
जो हम चाहते थे।
बिट-ट्विडलिंग हैक्स पेज से परिचित हों । मैं गारंटी देता हूं कि आप इनमें से कम से कम एक का उपयोग करेंगे।
कोड निष्पादन समय को मापने के लिए आपको अपने CPU के टाइमर परिधीय (एस) का उपयोग करना चाहिए - उनमें से अधिकांश में एक टाइमर / काउंटर होता है जिसे सीपीयू घड़ी आवृत्ति पर चलाने के लिए सेट किया जा सकता है। अपने महत्वपूर्ण कोड की शुरुआत और अंत में काउंटर की एक प्रति कैप्चर करें, और आप देख सकते हैं कि इसमें कितना समय लगता है। यदि आप ऐसा नहीं कर सकते हैं, तो एक और विकल्प आपके कोड की शुरुआत में आउटपुट पिन को कम करना है, और इसे अंत में बढ़ाएं, और निष्पादन के समय एक आस्टसीलस्कप पर इस आउटपुट को देखें। प्रत्येक दृष्टिकोण के लिए ट्रेडऑफ़ हैं: आंतरिक टाइमर / काउंटर अधिक लचीला है (आप कई चीजों को समय दे सकते हैं) लेकिन जानकारी प्राप्त करने के लिए कठिन है, जबकि आउटपुट पिन को सेट / क्लीयर करना तुरंत एक दायरे में दिखाई देता है और आप आंकड़ों पर कब्जा कर सकते हैं, लेकिन कई घटनाओं में अंतर करना कठिन है।
अंत में, एक बहुत ही महत्वपूर्ण कौशल है जो अनुभव के साथ आता है - दोनों सामान्य और विशिष्ट प्रोसेसर / संकलक संयोजन के साथ: यह जानना कि कब और कब अनुकूलन नहीं करना है । सामान्य तौर पर उत्तर का अनुकूलन नहीं होता है। डोनाल्ड नथ उद्धरण StackOverflow (आमतौर पर सिर्फ पिछले भाग) पर अक्सर पोस्ट किया जाता है:
हमें छोटी क्षमता के बारे में भूलना चाहिए, समय के 97% के बारे में कहना चाहिए: समय से पहले अनुकूलन सभी बुराई की जड़ है
लेकिन आप ऐसी स्थिति में हैं जहां आपको पता है कि आपको किसी प्रकार का अनुकूलन करना है, इसलिए बुलेट को काटने और अनुकूलन करने का समय है (या तेज़ प्रोसेसर, या दोनों) प्राप्त करें। करो नहीं विधानसभा में अपने पूरे ISR लिखें। यह लगभग एक गारंटीकृत आपदा है - यदि आप इसे करते हैं, तो महीनों या हफ्तों के भीतर आप जो कुछ भी करते हैं उसके कुछ हिस्सों को भूल जाते हैं और क्यों, और कोड बहुत भंगुर और बदलने में मुश्किल होता है। हालांकि, आपके कोड के कुछ भाग होने की संभावना है, हालांकि, विधानसभा के लिए अच्छे उम्मीदवार हैं ।
आपके कोड के कुछ भाग असेंबली-कोडिंग के लिए उपयुक्त हैं:
- ऐसे कार्य जो अच्छी तरह से सम्मिलित हैं, अच्छी तरह से परिभाषित छोटी दिनचर्याएँ बदलने की संभावना नहीं है
- ऐसे कार्य जो विशिष्ट विधानसभा निर्देशों (न्यूनतम / अधिकतम / सही बदलाव / आदि) का उपयोग कर सकते हैं
- ऐसे कार्य जिन्हें कई बार कॉल किया जाता है (आपको एक गुणक मिलता है: यदि आप प्रत्येक कॉल पर 0.5usec बचाते हैं, और इसे 10 बार कॉल किया जाता है, तो यह आपको 5 usec बचाता है जो आपके मामले में महत्वपूर्ण है)
अपने कंपाइलर के फंक्शन कॉलिंग कन्वेंशनों को जानें (जैसे कि जहां यह रजिस्टर में दलीलें डालता है, और जो इसे रजिस्टर करता है / उसे बचाता है) ताकि आप सी-कॉलेबल असेंबली रूट लिख सकें।
मेरे वर्तमान प्रोजेक्ट में, हमारे पास महत्वपूर्ण कोड के साथ एक बहुत बड़ा कोडबेस है जिसे 10kHz इंटरप्ट (100usec - sound परिचित) में चलाना है और विधानसभा में लिखे गए कई फ़ंक्शन नहीं हैं। जो हैं, वे सीआरसी गणना, सॉफ्टवेयर कतार, एडीसी लाभ / ऑफसेट क्षतिपूर्ति जैसी चीजें हैं।
सौभाग्य!