Arduino / AVR पर कोड के लिए मॉनिटर घड़ी चक्र?


11

क्या कोड के ब्लॉक की निगरानी करना और प्रोसेसर क्लॉक साइकिल की संख्या निर्धारित करना संभव है जो कोड एक Arduino और / या AVR Atmel प्रोसेसर पर लिया गया था? या, क्या मुझे कोड चलाने से पहले और बाद में पास किए गए माइक्रोसेकंड की निगरानी करनी चाहिए? ध्यान दें: मैं वास्तविक समय से संबंधित नहीं हूं (जैसा कि, कितने वास्तविक सेकंड पास हुए) जितना मैं "सीपीयू से इस कोड को कितने घड़ी चक्र की आवश्यकता है" में हूं।

वर्तमान समाधान मैं समय के साथ आ सकता हूं।

#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )

wiring.c कहते हैं:

#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )

इस खाते के द्वारा मैं घड़ी की शैलियों की गणना कर सकता हूं, जो पास किए गए माइक्रोसेकंड की निगरानी के द्वारा पारित की गई है और फिर उसे माइक्रोसेकंड टूक्लाकसाइकल () में पास कर सकते हैं। मेरा सवाल है, क्या कोई बेहतर तरीका है?

sidenote: वहाँ AVR के प्रदर्शन की निगरानी के लिए अच्छे संसाधन हैं। lmgtfy.com और विभिन्न फ़ोरम खोजें किसी भी स्पष्ट परिणाम प्रदान नहीं करती हैं, टाइमर की खोज के अलावा अन्य

धन्यवाद

जवाबों:


6

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


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

4

"मॉनिटर" से आपका क्या मतलब है?

विधानसभा कोड के छोटे टुकड़ों के लिए AVR के लिए घड़ी के चक्र को गिनना मुश्किल नहीं होना चाहिए।

कोड निष्पादित होने और बाद में रीसेट होने से पहले आप एक पोर्ट भी सेट कर सकते हैं, और मॉनिटर कर सकते हैं कि टाइमिंग पाने के लिए लॉजिक एनालाइज़र या ऑस्ज़िलोस्कोप के साथ।

और आप तेजी से चलने वाले टाइमर से समय भी पढ़ सकते हैं, जैसा कि आप कहते हैं।


मॉनिटर द्वारा मेरा मतलब है कि कोड द्वारा उपयोग किए जाने वाले चक्रों की संख्या निर्धारित करें। कुछ ऐसा (नोट, कोड का प्रारूपण संभवतः टिप्पणी इंजन द्वारा चपटा होगा): घड़ियाँ = startCountingAtmegaClocks (); for ... {for ... {digitalRead ...}} Serial.print ("प्रयुक्त चक्रों की संख्या:"); Serial.print (currentCountingAtmegaClocks () - घड़ियों, DEC);
साइबर

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

3

यह Arduino के लिए एक उदाहरण है जिसने क्लॉक साइकिल PerMicrosecond () फ़ंक्शन का उपयोग करके उन घड़ियों की गणना की है जो बीत चुके हैं। यह कोड 4 सेकंड प्रतीक्षा करेगा, फिर प्रोग्राम शुरू होने के बाद से पारित समय को प्रिंट करें। बाएं 3 मान कुल समय (माइक्रोसेकंड, मिलीसेकंड, कुल घड़ी चक्र) हैं और दाईं ओर 3 सबसे लंबे समय के हैं:

आउटपुट:

clocks for 1us:16
runtime us, ms, ck :: elapsed tme us, ms ck
4003236 4002	64051776	::	4003236	4002	64051760
8006668 8006	128106688	::	4003432	4004	64054912
12010508    12010	192168128	::	4003840	4004	64061440
16014348    16014	256229568	::	4003840	4004	64061440
20018188    20018	320291008	::	4003840	4004	64061440
24022028    24022	384352448	::	4003840	4004	64061440
28026892    28026	448430272	::	4004864	4004	64077824
32030732    32030	512491712	::	4003840	4004	64061440
36034572    36034	576553152	::	4003840	4004	64061440
40038412    40038	640614592	::	4003840	4004	64061440
44042252    44042	704676032	::	4003840	4004	64061440
48046092    48046	768737472	::	4003840	4004	64061440
52050956    52050	832815296	::	4004864	4004	64077824

मुझे यकीन है कि एक उचित स्पष्टीकरण है कि क्यों पहले छोरों में सबसे अधिक की तुलना में कम लम्बी घड़ी चक्र थे और क्यों अन्य सभी छोरों को घड़ी की लंबाई के दो चक्रों के बीच टॉगल करना था।

कोड:

unsigned long us, ms, ck;
unsigned long _us, _ms, _ck;
unsigned long __us, __ms, __ck;
void setup() {
        Serial.begin(9600);
}
boolean firstloop=1;
void loop() { 
        delay(4000);

        if (firstloop) {
                Serial.print("clocks for 1us:");
                ck=microsecondsToClockCycles(1);
                Serial.println(ck,DEC);
                firstloop--;
                Serial.println("runtime us, ms, ck :: elapsed tme us, ms ck");
        }

        _us=us;
        _ms=ms;
        _ck=ck;

        us=micros(); // us since program start
        ms=millis();
        //ms=us/1000;
        ck=microsecondsToClockCycles(us);
        Serial.print(us,DEC);
        Serial.print("\t");
        Serial.print(ms,DEC);
        Serial.print("\t");
        Serial.print(ck,DEC);     
        Serial.print("\t::\t");

        __us = us - _us;
        __ms = ms - _ms;
        __ck = ck - _ck;
        Serial.print(__us,DEC);
        Serial.print("\t");
        Serial.print(__ms,DEC);
        Serial.print("\t");
        Serial.println(__ck,DEC);     

}

सिडेनोट: यदि आप 4 सेकंड की देरी को हटाते हैं तो आपको Serial.print () के प्रभाव अधिक स्पष्ट रूप से दिखाई देने लगेंगे। ध्यान दें, यहां 2 रन की तुलना की जाती है। मैंने केवल उनके संबंधित लॉग से एक दूसरे के पास 4 नमूने शामिल किए हैं।

1 चलाएं:

5000604 5000	80009664	::	2516	2	40256
6001424 6001	96022784	::	2520	3	40320
7002184 7002	112034944	::	2600	3	41600
8001292 8001	128020672	::	2600	3	41600

रन 2:

5002460 5002	80039360	::	2524	3	40384
6000728 6000	96011648	::	2520	2	40320
7001452 7001	112023232	::	2600	3	41600
8000552 8000	128008832	::	2604	3	41664

बीता हुआ समय कुल रन समय में बढ़ जाता है। एक सेकंड के बीतने के बाद घड़ियां औसतन 40k से 44k तक बढ़ जाती हैं। यह 1 सेकंड के बाद लगातार कुछ मिलीसेकंड होता है और बीती हुई घड़ियां कम से कम अगले 10 सेकंड (मैं इसे और अधिक परीक्षण करता है) के लिए 44k के आसपास रहता है। यही कारण है कि निगरानी उपयोगी या आवश्यक है। शायद घटती दक्षता का सीरियल में विन्यास या बग के साथ क्या करना है? या शायद कोड ठीक से मेमोरी का उपयोग नहीं कर रहा है और एक रिसाव है जो प्रभाव प्रदर्शन, आदि।


कई साल बाद, मुझे अभी भी कुछ ऐसा चाहिए जो घड़ियों को कोड के साथ अधिक सटीक रूप से दिखाता है (जैसा कि एक आस्टसीलस्कप पर लगाया गया है)। मैं 16MHZ और 8MHZ दोनों में digitalWrite () के लिए आवश्यक घड़ी चक्रों की संख्या निर्धारित करने का प्रयास कर रहा हूं। 16MHZ में मुझे 8us / 64clk मिलता है। लेकिन 8MHZ में मुझे 0us / 0clk मिलता है।
साइफंक

1

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

मुझे सिर्फ "एनोटेट असेंबली फ़ाइल डीबगर" नामक एक Atmel स्टूडियो प्लगइन मिला। http://www.atmel.com/webdoc/aafdebugger/pr01.html ऐसा प्रतीत होता है कि वास्तविक जनरेट की गई असेंबली भाषा के माध्यम से कदम बढ़ा रहे हैं, जबकि शायद थकाऊ आपको दिखाने जा रहा है कि वास्तव में क्या हो रहा है। आपको अभी भी प्रत्येक निर्देश के लिए कितने चक्रों को डिकोड करना होगा, लेकिन यह कुछ अन्य पोस्ट किए गए विकल्पों की तुलना में बहुत करीब होगा।

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

परियोजना के गुण | टूलचैन | एवीआर / जीएनयू कॉमन | OutputFiles

चेकबॉक्स ".ls (lss फ़ाइल जनरेट करें)"


1

आप निर्मित टाइमर में से एक का उपयोग कर सकते हैं। ब्लॉक से पहले प्रेस्क्लर = 1 और टीसीएनटी = 0 के लिए सब कुछ प्राप्त करें। फिर ब्लॉक से पहले लाइन पर टाइमर को सक्षम करें और ब्लॉक के बाद लाइन पर इसे अक्षम करें। TCNT अब सक्षम और अक्षम कोड के लिए निर्धारित चक्रों को कम करने वाले चक्रों की संख्या को धारण करेगा।

ध्यान दें कि 16 बिट टाइमर पर 65535 घड़ी चक्र के बाद TNCT ओवरफ्लो हो जाएगा। आप ओवरफ्लो ध्वज का उपयोग डबल रन टाइम के लिए कर सकते हैं। यदि आपको अभी भी अधिक समय की आवश्यकता है, तो आप एक प्रीस्कूलर का उपयोग कर सकते हैं, लेकिन कम संकल्प प्राप्त करेंगे।

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