क्या तेज प्रोसेसर / घड़ियां अधिक कोड निष्पादित कर सकती हैं?


9

मैं एक ATmega 328 पर चलने के लिए एक कार्यक्रम लिख रहा हूं जो 16Mhz पर चलता है (इसकी एक Arduino Duemilanove यदि आप उन्हें जानते हैं, तो यह एक AVR चिप है)।

मेरे पास प्रत्येक 100 माइक्रोसेकंड चलने वाली एक बाधा प्रक्रिया है। यह असंभव है, मैं कहूंगा कि 100 माइक्रोसेकंड के एक लूप में आप कितना "कोड" निष्पादित कर सकते हैं (मैं सी में लिख रहा हूं जो संभवतः विधानसभा में तब द्विआधारी छवि में बदल जाता है?)।

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

क्या मेरी समझ सही है, जिसमें मेरा प्रोसेसर क्लॉक रेट या 16 मेगाहर्ट्ज 16 मिलियन चक्र प्रति सेकंड करता है (इसका मतलब है 16 चक्र प्रति माइक्रोसेकंड 16,000,000 / 1,000 / 1,000); और इसलिए, अगर मैं अपने 100 माइक्रोसेकंड लूप में अधिक करना चाहता हूं, तो 72Mhz संस्करण की तरह एक तेज मॉडल खरीदने से मुझे प्रति माइक्रोसॉन्ड (72,000,000 / 1,000 / 1,000) प्रति 72 चक्र मिलेगा?

वर्तमान में यह थोड़ी धीमी गति से चलता है, अर्थात इसका लूप करने के लिए 100 माइक्रोसेकंड से थोड़ा अधिक समय लगता है (कहने के लिए कितनी देर तक यह कहना बहुत कठिन है, लेकिन यह धीरे-धीरे पीछे छूट जाता है) और मैं चाहूंगा कि यह थोड़ा और हो, यह एक तेज़ दृष्टिकोण वाला एक तेज़ दृष्टिकोण है या मैं पागल हो गया हूं?


.... एक ATmega328 एआरएम चिप नहीं है। यह एक एवीआर है।
vicatcu

चीयर्स, सही!
jwbensley

जवाबों:


9

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

प्रति सेकंड निर्देशों की प्रभावी संख्या निर्धारित करने की समस्या को अधिक जटिल प्रोसेसर में इस तथ्य से उतारा जाता है कि वे पाइपलाइज्ड हैं और उनमें कैश हैं और क्या नहीं। यह एक साधारण डिवाइस जैसे ATMega328 के लिए नहीं है जो फ्लाइट प्रोसेसर में एकल निर्देश है।

व्यावहारिक मामलों के लिए, AVR जैसे सरल उपकरण के लिए, मेरा उत्तर कम या ज्यादा "हां" होगा। अपनी घड़ी की गति को दोगुना करने के लिए किसी भी फ़ंक्शन का निष्पादन समय आधा होना चाहिए। एक AVR के लिए, हालांकि, वे 20MHz से अधिक तेज़ी से नहीं चलेंगे, इसलिए आप केवल 4MHz द्वारा अपने Arduino को "ओवरक्लॉक" कर सकते हैं।

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


नमस्ते, आपके जानकारीपूर्ण उत्तर के लिए धन्यवाद! मैंने इनमें से एक को देखा है ( coolcompords.co.uk/catalog/product_info.php?products_id=808 ), आपने कहा कि AVR 20Mhz से अधिक तेजी से नहीं जा सकता है, ऐसा क्यों है? उपरोक्त बोर्ड पर चिप ( uk.farnell.com/stmicroelectronics/stm32f103rbt6/… ) एक 72Mhz एआरएम है, क्या मैं ऊपर बताए गए तरीके से इससे एक उचित प्रदर्शन वृद्धि की उम्मीद कर सकता हूं?
jwbensley

2
प्रसंस्करण गति को दोगुना करने से आपके निर्देश थ्रूपुट में वृद्धि नहीं कर सकते हैं क्योंकि आप उस गति को पार कर सकते हैं जिस पर फ्लैश से निर्देश प्राप्त किया जा सकता है। इस बिंदु पर आप "फ्लैश वेट स्टेट्स" मारना शुरू करते हैं, जहां सीपीयू रुकता है, जबकि यह फ्लैश से आने के निर्देश का इंतजार करता है। कुछ माइक्रोकंट्रोलर आपको इस तरह से मिलते हैं कि आप RAM से कोड निष्पादित कर सकते हैं जो कि FLASH से बहुत तेज है।
मैजेंको

@ माजेंको: मजाकिया, हम दोनों ने एक ही समय में एक ही बिंदु बनाया।
जेसन एस

ऐसा होता है ... तुम्हारा मेरा से बेहतर है :)
माज़ेंको

1
ठीक है, मैंने विकटसु के उत्तर को "उत्तर" के रूप में चिह्नित किया है। मुझे लगता है कि प्रदर्शन से संबंधित गति के मेरे मूल प्रश्न के संबंध में यह सबसे उपयुक्त था, हालांकि सभी उत्तर महान हैं और मैं वास्तव में सभी के उत्तरों से प्रभावित हूं। उन्होंने मुझे दिखाया है कि यह एक व्यापक विषय है जो मैंने पहली बार महसूस किया था, और इसलिए, वे सभी मुझे बहुत कुछ सिखा रहे हैं और मुझे बहुत सारे शोध दे रहे हैं, इसलिए सभी को धन्यवाद: D
jwbensley

8

@ 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 परिचित) में चलाना है और विधानसभा में लिखे गए कई फ़ंक्शन नहीं हैं। जो हैं, वे सीआरसी गणना, सॉफ्टवेयर कतार, एडीसी लाभ / ऑफसेट क्षतिपूर्ति जैसी चीजें हैं।

सौभाग्य!


अनुभवजन्य निष्पादन समय मापन तकनीकों पर अच्छी सलाह
vicatcu

मेरे सवाल का एक और शानदार जवाब, ज्ञान के इस भयानक भाग के लिए बहुत बहुत धन्यवाद जेसन एस! इसे पढ़ने के बाद स्पष्ट दो बातें; सबसे पहले, मैं कोड को निष्पादित करने के लिए अधिक समय देने के लिए प्रत्येक 100uS से 500uS तक की रुकावट को बढ़ा सकता हूं, मुझे एहसास है कि अब यह वास्तव में मुझे इतनी तेजी से लाभ नहीं पहुंचा रहा है। दूसरे मुझे लगता है कि मेरा कोड शायद बहुत अक्षम है, लंबे समय तक बाधित होने वाले समय और बेहतर कोड के साथ यह सब ठीक हो सकता है। Stackoverflow कोड को पोस्ट करने के लिए एक बेहतर जगह है, इसलिए मैं इसे वहां पोस्ट करूंगा और इसे यहां एक लिंक डालूंगा, अगर कोई देखना चाहता है और कोई सिफारिश करना चाहता है तो कृपया: D
jwbensley

5

एक और बात ध्यान दें - आपके कोड को अधिक कुशल बनाने के लिए संभवतः कुछ अनुकूलन हैं जो आप कर सकते हैं।

उदाहरण के लिए - मेरी एक दिनचर्या है जो एक टाइमर बाधा के भीतर से चलती है। दिनचर्या को 52µS के भीतर पूरा करना पड़ता है, और इसे करते समय बड़ी मात्रा में मेमोरी से गुजरना पड़ता है।

मैंने मुख्य काउंटर वैरिएबल को एक रजिस्टर पर (मेरे largeC और कंपाइलर पर - आपके लिए अलग) के साथ लॉक करके एक बड़ी गति वृद्धि को प्रबंधित किया:

register unsigned int pointer asm("W9");

मुझे आपके संकलक - आरटीएफएम के लिए प्रारूप का पता नहीं है, लेकिन कुछ ऐसा होगा जो आप अपनी दिनचर्या को विधानसभा में बदलने के बिना तेजी से कर सकते हैं।

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


lol I "एक ​​साथ" कोडांतरक ट्यूनिंग और रजिस्टर आवंटन के बारे में मेरे अपने जवाब पर टिप्पणी की :)
vicatcu

यदि यह 16 मेगाहर्ट्ज प्रोसेसर पर 100us ले रहा है - यह स्पष्ट रूप से बहुत बड़ा है, तो यह अनुकूलन करने के लिए कोड का एक बहुत कुछ है। मैंने सुना है कि आज संकलक हाथ से चुने हुए असेंबली की तुलना में कोड का लगभग 1.1 गुना उत्पादन करते हैं। इतनी बड़ी दिनचर्या के लिए पूरी तरह से इसके लायक नहीं। 6 लाइन फंक्शन से 20% शेविंग के लिए, शायद ...
डिफेनेस्ट्रेशनडाई

1
जरूरी नहीं ... यह लूप में कोड की सिर्फ 5 पंक्तियां हो सकती हैं। और यह कोड आकार के बारे में नहीं बल्कि कोड दक्षता के बारे में है । हो सकता है कि आप कोड को अलग-अलग लिखने में सक्षम हों, जिससे यह तेजी से चले। मैं अपनी रुकावट दिनचर्या के लिए जानता हूं जो मैंने किया। उदाहरण के लिए, गति के लिए आकार का त्याग। उसी कोड को 10 बार क्रम से चलाकर आप लूप - और संबद्ध काउंटर वेरिएबल को कोड करने का समय बचाते हैं। हां, कोड 10 गुना लंबा है, लेकिन यह तेजी से चलता है।
मजनू

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

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