c एलडीएम/एसटीएम निर्देशों को एआरएम कंपाइलर 5 बार्ससीसी इनलाइन कोडांतरक में कैसे रोकें?



assembly arm (1)

मैं एसएटीआई / एलडीएम निर्देशों का प्रयोग कर एएक्सआई बस फट उत्पन्न करने की कोशिश कर रहा हूं, जिसमें एआरएम कंपाइलर 5 आर्मक के साथ संकलित इन।

inline void STMIA2(uint32_t addr, uint32_t w0, uint32_t w1)
{
    __asm {
        STMIA addr!, { w0, w1 }
    }
}

लेकिन एआरएम कंपाइलर आर्मकेक्स उपयोगकर्ता गाइड, पैराग्राफ 7.18 कह रहा है: "सभी एलडीएम और एसटीएम निर्देश एलडीआर और एसटीआर निर्देशों के अनुक्रम में समतुल्य प्रभाव के साथ विस्तारित हैं। हालांकि, अनुकूलन के दौरान संकलक बाद में एलडीएम या एसटीएम में अलग-अलग निर्देशों को पुनः संयोजित कर सकता है। "

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

इसे हल करने के लिए इनलाइन कोडांतरक के बजाय एम्बेडेड एन्बलर का उपयोग करना संभव है, लेकिन इससे अतिरिक्त फ़ंक्शन कॉल-रिटर्न जो प्रदर्शन को प्रभावित करता है।

तो मैं सोच रहा हूं कि एलडीएम / एसटीएम को प्रदर्शन खोने के बिना उत्पन्न करने का एक रास्ता है? हम जीसीसी में ऐसा करने में सक्षम थे, लेकिन आर्मकैक के लिए कोई समाधान नहीं मिला।

लक्ष्य सीपीयू: कॉर्टेक्स एम 0 + (एआरएमवी 6-एम)

संपादित करें: स्लेव डिवाइस सभी ऑन-चिप डिवाइस हैं, जिनमें से अधिकांश गैर-मेमोरी डिवाइस हैं गैर-मेमोरी स्लेव के प्रत्येक रजिस्टर के लिए जो पता स्थान के फट पहुंच क्षेत्र का समर्थन करता है आरक्षित है (उदाहरण के लिए [0x10000..0x10100]), मुझे पूरी तरह से यकीन नहीं है कि क्यों, सीपीयू या बस फिक्स्ड (गैर-वृद्धिशील ) पते एचडब्ल्यू इस क्षेत्र के भीतर ऑफ़सेट की अनदेखी करता है उदाहरण के लिए पूर्ण अनुरोध 16 बाइट्स हो सकते हैं और पूर्ण अनुरोध का पहला शब्द पहली बार लिखा गया शब्द है (भले ही ऑफ़सेट शून्य है)।


तो मैं सोच रहा हूं कि एलडीएम / एसटीएम को प्रदर्शन खोने के बिना उत्पन्न करने का एक रास्ता है? हम जीसीसी में ऐसा करने में सक्षम थे, लेकिन आर्मकैक के लिए कोई समाधान नहीं मिला।

संकलक ऑप्टिमाइज़ेशन के बारे में थोड़ा सा। रजिस्टर आवंटन यह सबसे कठिन काम है। किसी भी कंपाइलर कोड पीढ़ी का दिल संभवत: आसपास है जब यह भौतिक CPU रजिस्टरों को आवंटित करता है ज्यादातर कम्पाइलर अपने 'सी' चर को छद्म चर (या समय क्रम चर) के एक गुच्छा में बदलने के लिए सिंगल स्टैटिक असाइनमेंट या एसएसए का उपयोग कर रहे हैं।

आपके एसटीएमआईए और एलडीएमआईए के काम करने के लिए आपको लगातार लोड होने और लोड करने की आवश्यकता है। Ie, अगर यह stmia [rx], {r3,r7} ldmia [rx], {r4,r8} , ldmia [rx], {r4,r8} stmia [rx], {r3,r7} और एक 'आर 4' और 'आर 7' मैपिंग के लिए 'आर 3' मैपिंग के साथ ldmia [rx], {r4,r8} , ldmia [rx], {r4,r8} , ldmia [rx], {r4,r8} तरह बहाल बहाल 'आर 8' यह किसी भी कंपाइलर के लिए सामान्य रूप से लागू करने के लिए आसान नहीं है क्योंकि 'सी' चर की आवश्यकता के मुताबिक असाइन किया जाएगा। अलग-अलग रजिस्टरों में एक ही चर के विभिन्न संस्करण। stm/ldm काम करने के लिए उन वेरिएबल को आवंटित किया जाना चाहिए ताकि सही क्रम में पंजीकरण की वृद्धि हो। यानी, अगर ऊपर ldmia लिए संकलक ldmia (शायद एक रिटर्न वैल्यू?) में संग्रहीत ldmia चाहते हैं, तो अतिरिक्त कोड उत्पन्न किए बिना एक अच्छा ldm निर्देश बनाने के लिए कोई रास्ता नहीं है।

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

देखें: जीसीसी एसटीएम / एलडीएम के साथ मुद्दों के लिए एलडीएम / एसटीएम और जीसीसी

अपना उदाहरण लेना,

inline void STMIA2(uint32_t addr, uint32_t w0, uint32_t w1)
{
    __asm {
        STMIA addr!, { w0, w1 }
    }
}

inline का मान है कि पूरे फ़ंक्शन बॉडी को कोड में सही रखा जा सकता है। कॉलर में आर 2 और आर 4 के रजिस्टरों में w0 और w1 हो सकता है यदि फ़ंक्शन inline नहीं है, तो संकलन को उन्हें R1 और R2 में रखना चाहिए, लेकिन अतिरिक्त चालें उत्पन्न हो सकती हैं किसी भी संकलक के लिए सामान्य रूप से ldm/stm की आवश्यकताओं को पूरा करना मुश्किल है

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

यदि हार्डवेयर बस पर एक विशेष गैर-स्मृति दास परिधीय है, तो आप इस दास को बाहरी आवरण में लिखने के लिए कार्यक्षमता को लपेट सकते हैं और रजिस्टर आवंटन को मजबूर कर सकते हैं ( एएपीसीएस देखें) ताकि ldm/stm काम करे। इससे एक निष्पादन हिट होगा जो डिवाइस के लिए चालक में कुछ कस्टम कोडल द्वारा कम किया जा सकता है।

हालांकि, यह लगता है कि डिवाइस मेमोरी हो सकती है? इस मामले में, आपके पास एक समस्या है आम तौर पर, ऐसे मेमोरी डिवाइस केवल कैश का उपयोग करेंगे? यदि आपके सीपीयू में एक एमपीयू (मेमोरी संरक्षण इकाई) है और डेटा और कोड कैश दोनों सक्षम कर सकते हैं, तो आप इस समस्या को हल कर सकते हैं। कैश लाइनें हमेशा फट हो जाएंगी। MPU और डेटा कैश को सेटअप करने के लिए कोड में देखभाल की आवश्यकता है। ओ पी कॉर्टेक्स-एम 0 + में कोई कैश नहीं है और डिवाइस गैर-मेमोरी हैं इसलिए यह संभव नहीं होगा (और न ही आवश्यक)।

यदि आपकी डिवाइस मेमोरी है और आपके पास कोई डेटा कैश नहीं है तो आपकी समस्या शायद असाधारण है (बड़े पैमाने पर प्रयास किए बिना) और आपको अलग हार्डवेयर की आवश्यकता है या आप इसे परिधीय डिवाइस की तरह रख सकते हैं और एक प्रदर्शन हिट ले सकते हैं; स्मृति डिवाइस के यादृच्छिक उपयोग के लाभ खोने





armcc