2016-01-20 10 views
5

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

क्या कोई जानता है कि जीसीसी किस तरह से बाहर निकलता है और केवल मेरे अंतर्निहित कोड को कोड में अनुवादित करता है?

यहां एक उदाहरण दिया गया है: मेरे पास एक साधारण लूप है जो फ़्लोटिंग पॉइंट मानों को अस्वीकार करता है और कॉपी करता है। यह स्मृति के लोड होने के लिए कुछ समय और निष्पादित करने के निर्देशों को अनुमति देने के लिए 4 समय के 4 सेट के साथ काम करता है। बहुत से रजिस्टरों को छोड़ दिया गया है, इसलिए चीजों को इतनी बुरी तरह उलझाने का कोई कारण नहीं है।

vld1.32 {d18-d19}, [r5] 
vneg.f32 q9,q9  <-- GCC intentionally causes stalls 
add r7,r7,#16 
vld1.32 {d22-d23}, [r8] 
add r5,r1,r4 
vneg.f32 q11,q11 <-- all of my interleaving is undone (why?!!?) 
add r8,r3,#256 
vld1.32 {d20-d21}, [r10] 
add r4,r1,r3 
vneg.f32 q10,q10 
add lr,r1,lr 
vld1.32 {d16-d17}, [r9] 
add ip,r1,ip 
vneg.f32 q8,q8 

और जानकारी:: Raspbian

  • संकलक झंडे के लिए

    • जीसीसी 4.9.2: -c -fPIE -march=armv7-a -Wall -O3 -mfloat-abi=hard -mfpu=neon

    जब

    float32x4_t f32_0, f32_1, f32_2, f32_3; 
    int x; 
    for (x=0; x<n-15; x+=16) 
    { 
        f32_0 = vld1q_f32(&s[x]); 
        f32_1 = vld1q_f32(&s[x+4]); 
        f32_2 = vld1q_f32(&s[x+8]); 
        f32_3 = vld1q_f32(&s[x+12]); 
        __builtin_prefetch(&s[x+64]); 
        f32_0 = vnegq_f32(f32_0); 
        f32_1 = vnegq_f32(f32_1); 
        f32_2 = vnegq_f32(f32_2); 
        f32_3 = vnegq_f32(f32_3); 
        vst1q_f32(&d[x], f32_0); 
        vst1q_f32(&d[x+4], f32_1); 
        vst1q_f32(&d[x+8], f32_2); 
        vst1q_f32(&d[x+12], f32_3); 
    } 
    

    इस कोड उत्पन्न है मैं वें लिखता हूँ एएसएम कोड में ई लूप बिल्कुल मेरे इंट्रिनिक्स के रूप में पैटर्न किया गया है (कुछ मुफ्त एआरएम चक्र प्राप्त करने के लिए अतिरिक्त स्रोत/dest रजिस्टरों का उपयोग किए बिना), यह अभी भी जीसीसी के कोड से तेज़ है।

    अद्यतन: मैं जेम्स के उत्तर की सराहना करता हूं, लेकिन चीजों की योजना में, यह वास्तव में समस्या से मदद नहीं करता है। मेरे कार्यों का सबसे सरल कॉर्टेक्स-ए 7 विकल्प के साथ थोड़ा बेहतर प्रदर्शन करता है, लेकिन बहुमत में कोई बदलाव नहीं आया। दुखी सच यह है कि जीसीसी का आंतरिक ज्ञान का अनुकूलन बहुत अच्छा नहीं है। जब मैंने कुछ साल पहले माइक्रोसॉफ्ट एआरएम कंपाइलर के साथ काम किया था, तो लगातार एनईओएन इंट्रिनिक्स के लिए अच्छी तरह तैयार किए गए आउटपुट का निर्माण हुआ, जबकि जीसीसी लगातार ठोकर खाई। जीसीसी 4.9.एक्स के साथ, कुछ भी नहीं बदला है। मैं निश्चित रूप से जीसीसी की एफओएसएस प्रकृति और अधिक जीएनयू प्रयास की सराहना करता हूं, लेकिन इंटेल, माइक्रोसॉफ्ट या यहां तक ​​कि एआरएम के कंपाइलर्स के रूप में यह अच्छा काम नहीं करता है।

  • +0

    मुझे कोई जानकारी नहीं है। एक कंपाइलर बग या सीधे असेंबली लिखने पर विचार करें। आम तौर पर, आंतरिक अंतर्निहित कार्यों की तरह इंट्रिनिक्स को संभाला जाता है। इस बात की कोई गारंटी नहीं है कि संकलक उसी क्रम में निर्देशों को उत्सर्जित करता है जिसमें अंतर्निहित लिखा गया है। – fuz

    +4

    उपयोगी जानकारी जीसीसी का संस्करण होगा जिसका उपयोग आप सीपीयू के साथ कर रहे हैं (-mcpu = ??? या -mtune = ???) के लिए। आम तौर पर जवाब यह है, क्योंकि जीसीसी का मानना ​​है कि इंटरलेविंग के परिणामस्वरूप आप इंटरसेविंग के बेहतर प्रोसेसर उपयोग में परिणामों का उपयोग कर रहे हैं। एक और सवाल यह होगा कि आप कैसे पता लगा रहे हैं कि स्टॉल हैं? –

    +0

    @ जेम्स कंपाइलर जानकारी के लिए ऊपर देखें। मैंने अपनी शैली में एएसएम कोड लिखा है और यह जीसीसी के कोड से तेज़ है। लक्ष्य सीपीयू कॉर्टेक्स-ए 7 है। – BitBank

    उत्तर

    8

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

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

    एक -mcpu या -mtune विकल्प (संकलक करने के लिए) के बिना

    , या एक --with-cpu, या --with-tune विकल्प (संकलक के विन्यास के लिए), एआरएम या AArch64 के लिए जीसीसी वास्तुकला संशोधन आप कर रहे हैं के लिए एक प्रतिनिधि मॉडल का उपयोग करने की कोशिश करेंगे लक्ष्य करते हुए।इस मामले में, -march=armv7-a, संकलक को निर्देशों को निर्धारित करने का प्रयास करने का कारण बनता है जैसे -mtune=cortex-a8 कमांड लाइन पर पारित किया गया था।

    तो आप अपने आउटपुट में जो देख रहे हैं वह आपके इनपुट को एक शेड्यूल में बदलने के लिए जीसीसी का प्रयास है, जो कॉर्टेक्स-ए 8 पर चलते समय अच्छी तरह से निष्पादित होने की अपेक्षा करता है, और एआरएमवी 7-ए आर्किटेक्चर को लागू करने वाले प्रोसेसर पर उचित रूप से अच्छी तरह से चलाने के लिए ।

    इस पर सुधार करने के लिए आप की कोशिश कर सकते हैं:

    • स्पष्ट रूप से प्रोसेसर आप लक्षित कर रहे स्थापित करने (-mcpu=cortex-a7)
    • पूरी तरह से समय निर्धारण अनुदेश अक्षम करना (`-fno-अनुसूची-insns -fno-अनुसूची-insns2)

    ध्यान दें कि निर्देश शेड्यूलिंग को पूरी तरह अक्षम करने से आपको कहीं और समस्याएं हो सकती हैं, क्योंकि जीसीसी अब आपके कोड में पाइपलाइन खतरों को कम करने की कोशिश नहीं कर रहा है।

    संपादित के साथ अपने संपादित करने के संबंध, जीसीसी में प्रदर्शन कीड़े जीसीसी बगजिला में सूचना दी जा सकती है (https://gcc.gnu.org/bugs/ देखें) बस के रूप में शुद्धता कीड़े हो सकता है। स्वाभाविक रूप से सभी अनुकूलन के साथ कुछ हद तक ह्युरिस्टिक शामिल है और एक कंपाइलर अनुभवी असेंबली प्रोग्रामर को हरा नहीं सकता है, लेकिन यदि संकलक कुछ विशेष रूप से आक्रामक कर रहा है तो यह हाइलाइटिंग के लायक हो सकता है।

    संबंधित मुद्दे