मैं एआरएम कॉर्टेक्स-एम 4 (या कॉर्टेक्स-एम 3) प्रोसेसर पर निष्पादित प्रति चक्र निर्देशों की संख्या गिनना चाहता हूं।एआरएम एम 4 निर्देश प्रति चक्र (आईपीसी) काउंटर
यह क्या जरूरत है: कोड के निर्देश (रनटाइम पर निष्पादित) के संख्या मैं प्रोफ़ाइल करना चाहते हैं और उस कोड निष्पादित करने के लिए लेता है चक्र की संख्या।
1 - साइकिल
की संख्या का प्रयोग करें चक्र काउंटर काफी आसान और सरल है।
volatile unsigned int *DWT_CYCCNT ;
volatile unsigned int *DWT_CONTROL ;
volatile unsigned int *SCB_DEMCR ;
void reset_timer(){
DWT_CYCCNT = (int *)0xE0001004; //address of the register
DWT_CONTROL = (int *)0xE0001000; //address of the register
SCB_DEMCR = (int *)0xE000EDFC; //address of the register
*SCB_DEMCR = *SCB_DEMCR | 0x01000000;
*DWT_CYCCNT = 0; // reset the counter
*DWT_CONTROL = 0;
}
void start_timer(){
*DWT_CONTROL = *DWT_CONTROL | 1 ; // enable the counter
}
void stop_timer(){
*DWT_CONTROL = *DWT_CONTROL | 0 ; // disable the counter
}
unsigned int getCycles(){
return *DWT_CYCCNT;
}
main(){
....
reset_timer(); //reset timer
start_timer(); //start timer
//Code to profile
...
myFunction();
...
stop_timer(); //stop timer
numCycles = getCycles(); //read number of cycles
...
}
2 - निर्देश
मैं इंटरनेट पर सर्फिंग हाथ प्रांतस्था-एम 3 द्वारा निष्पादित निर्देश और की संख्या की गणना करने के लिए प्रांतस्था-एम 4 (link) कुछ प्रलेखन पाया की संख्या:
# instructions = CYCCNT - CPICNT - EXCCNT - SLEEPCNT - LSUCNT + FOLDCNT
वे जिन रजिस्टरों का उल्लेख करते हैं उन्हें here (पृष्ठ 11-13 से) दस्तावेज किया गया है और इन्हें एक्सेस करने के लिए स्मृति पते हैं:
DWT_CYCCNT = 0xE0001004
DWT_CONTROL = 0xE0001000
SCB_DEMCR = 0xE000EDFC
DWT_CPICNT = 0xE0001008
DWT_EXCCNT = 0xE000100C
DWT_SLEEPCNT = 0xE0001010
DWT_LSUCNT = 0xE0001014
DWT_FOLDCNT = 0xE0001018
DWT_CONTROL रजिस्टर काउंटर को सक्षम करने के लिए उपयोग किया जाता है, विशेष रूप से साइकिल काउंटर here दस्तावेज के रूप में।
लेकिन जब मैंने प्रति चक्र निष्पादित निर्देशों की संख्या गिनने के लिए सभी को एक साथ रखने की कोशिश की तो मैं सफल नहीं हुआ।
Here जीडीबी से उनका उपयोग करने के तरीके पर एक छोटी सी मार्गदर्शिका है।
क्या आसान नहीं है कि कुछ रजिस्ट्रार 8 बिट रजिस्ट्रार (DWT_CPICNT, DWT_EXCCNT, DWT_SLEEPCNT, DWT_LSUCNT, DWT_FOLDCNT) हैं और जब वे बहते हैं तो वे एक ईवेंट ट्रिगर करते हैं। मुझे उस घटना को इकट्ठा करने का कोई रास्ता नहीं मिला। कोई कोड स्निपेट नहीं है जो बताता है कि ऐसा कैसे करें या इसके लिए उपयुक्त रूटीन को बाधित करें।
ऐसा लगता है कि उन रजिस्टरों के पते पर gdb से watchpoints का उपयोग करना काम नहीं करता है। रजिस्ट्रार मूल्य बदलते समय gdb रुकने में सक्षम नहीं है। जैसे
(gdb) watch *0xE0001014
अपडेट:: DWT_LSUCNT पर मैं डीडब्ल्यूटी, आईटीएम और ETM इकाइयों का उपयोग करने का तरीका बताने GitHub पर इस project पाया। लेकिन मैंने यह नहीं देखा कि यह काम करता है या नहीं! मैं अपडेट पोस्ट करूंगा।
उनका उपयोग करने के तरीके पर कोई विचार?
धन्यवाद!
शायद बहुत स्पष्ट है, लेकिन आप हमेशा reset_timer() किसी अन्य समारोह के निष्पादित होने से पहले, सही कहते हैं? क्या आप कम से कम उदाहरण के रूप में कॉलिंग कोड पोस्ट कर सकते हैं? – Lundin
मैं रजिस्ट्रार को '# परिभाषित DWT_CYCCNT (* (अस्थिर uint32_t *) 0xE0001004ul) के बजाय घोषित करने का सुझाव दूंगा। – Lundin
क्या ईवेंट ऐसी घटनाओं को डीबग नहीं करते हैं जो डीबग मॉनिटर अपवाद को ट्रिगर करेंगे? – Notlikethat