paint-brush
कंपाइलर अनुकूलन: न्यूनतम बदलाव के साथ कोड प्रदर्शन को बढ़ावा देना!द्वारा@durganshu
1,418 रीडिंग
1,418 रीडिंग

कंपाइलर अनुकूलन: न्यूनतम बदलाव के साथ कोड प्रदर्शन को बढ़ावा देना!

द्वारा Durganshu Mishra13m2023/11/30
Read on Terminal Reader

बहुत लंबा; पढ़ने के लिए

जो डेवलपर्स अपने C++ कोड के प्रदर्शन को अनुकूलित करना चाहते हैं, उन्हें कंपाइलर ऑप्टिमाइज़ेशन की खोज करनी चाहिए: बहुत प्रभावी C++ फ़्लैग का एक सेट जो बिना अधिक प्रयास के कोड के प्रदर्शन में सुधार करता है। एकमात्र शर्त यह है कि आप जानते हैं कि आप क्या कर रहे हैं। जैकोबी पुनरावृत्ति सी++ कोड पर व्यावहारिक तसलीम के साथ इंटेल सी++ कंपाइलर्स जैसे -fno-alias, -xHost, -xCORE-AVX512, IPO इत्यादि के लिए उपयुक्त फ़्लैग का अन्वेषण करें।
featured image - कंपाइलर अनुकूलन: न्यूनतम बदलाव के साथ कोड प्रदर्शन को बढ़ावा देना!
Durganshu Mishra HackerNoon profile picture
0-item
1-item


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


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


इस लेख का उद्देश्य इंटेल सी++ कंपाइलर्स पर ध्यान केंद्रित करते हुए कंपाइलर अनुकूलन की क्षमता पर प्रकाश डालना है - जो अपनी लोकप्रियता और व्यापक उपयोग के लिए प्रसिद्ध है।


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


मुख्य विशेषताएं: कंपाइलर अनुकूलन क्या हैं? | -पर | वास्तु लक्षित | अंतरप्रक्रियात्मक अनुकूलन | -fno-एलियासिंग | कंपाइलर अनुकूलन रिपोर्ट

कंपाइलर अनुकूलन क्या हैं?

कंपाइलर अनुकूलन विभिन्न तकनीकों और परिवर्तनों को शामिल करता है जो कंपाइलर संकलन के दौरान स्रोत कोड पर लागू करता है। लेकिन क्यों? प्रदर्शन, दक्षता और, कुछ मामलों में, परिणामी मशीन कोड के आकार को बढ़ाने के लिए। ये अनुकूलन गति, मेमोरी उपयोग और ऊर्जा खपत सहित कोड निष्पादन के विभिन्न पहलुओं को प्रभावित करने में महत्वपूर्ण हैं।


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


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


मैं सभी उपलब्ध विकल्पों पर चर्चा नहीं करने जा रहा हूं, लेकिन हम कंपाइलर को विशिष्ट अनुकूलन करने के लिए कैसे निर्देश दे सकते हैं जो कोड प्रदर्शन में सुधार कर सकता है। तो, समाधान ???? संकलक झंडे.

डेवलपर्स संकलन प्रक्रिया के दौरान कंपाइलर फ़्लैग का एक सेट निर्दिष्ट कर सकते हैं, जो डिबगिंग और प्रोफ़ाइलिंग जानकारी के लिए जीसीसी के साथ " -जी" या "-पीजी" जैसे विकल्पों का उपयोग करने वालों के लिए परिचित अभ्यास है। जैसे-जैसे हम आगे बढ़ेंगे, हम ऐसे ही कंपाइलर फ़्लैग पर चर्चा करेंगे जिनका उपयोग हम Intel C++ कंपाइलर के साथ अपने एप्लिकेशन को संकलित करते समय कर सकते हैं। ये आपके कोड की दक्षता और प्रदर्शन को बेहतर बनाने में आपकी मदद कर सकते हैं।


सीएएफ द्वारा गो किक ऑफ जीआईएफ



तो, हम किसके साथ काम कर रहे हैं?

मैं शुष्क सिद्धांत में नहीं जाऊंगा या आपको प्रत्येक संकलक ध्वज को सूचीबद्ध करने वाले कठिन दस्तावेज़ों से नहीं भरूंगा। इसके बजाय, आइए यह समझने की कोशिश करें कि ये झंडे क्यों और कैसे काम करते हैं।


हम इसे कैसे पूरा करें???


हम जेकोबी पुनरावृत्ति की गणना के लिए जिम्मेदार एक गैर-अनुकूलित C++ फ़ंक्शन लेंगे, और चरण दर चरण, हम प्रत्येक कंपाइलर ध्वज के प्रभाव को उजागर करेंगे। इस अन्वेषण के साथ, हम प्रत्येक पुनरावृत्ति की आधार संस्करण के साथ व्यवस्थित रूप से तुलना करके गति को मापेंगे - बिना किसी अनुकूलन झंडे (-O0) के साथ शुरू करके।


स्पीडअप (या निष्पादन समय) को Intel® Xeon® प्लैटिनम 8174 प्रोसेसर मशीन पर मापा गया था। यहां, जैकोबी विधि एक आयताकार ग्रिड पर गर्मी वितरण के मॉडलिंग के लिए 2डी आंशिक अंतर समीकरण (पॉइसन समीकरण) को हल करती है।


जैकोबी विधि


u(x,y,t) समय t पर बिंदु (x,y) पर तापमान है।


जब वितरण अब नहीं बदल रहा हो तो हम स्थिर स्थिति का समाधान करते हैं:

स्थिर स्थिति का समाधान


सीमा पर डिरिचलेट सीमा शर्तों का एक सेट लागू किया गया है।


हमारे पास अनिवार्य रूप से एक C++ कोडिंग है जो वैरिएबल आकारों (जिसे हम रिज़ॉल्यूशन कहते हैं) के ग्रिड पर जैकोबी पुनरावृत्तियों का प्रदर्शन करती है। मूल रूप से, 500 के ग्रिड आकार का अर्थ है 500x500 आकार के मैट्रिक्स को हल करना, इत्यादि।


एक जैकोबी पुनरावृत्ति को निष्पादित करने का कार्य इस प्रकार है:


 /* * One Jacobi iteration step */ void jacobi(double *u, double *unew, unsigned sizex, unsigned sizey) { int i, j; for (j = 1; j < sizex - 1; j++) { for (i = 1; i < sizey - 1; i++) { unew[i * sizex + j] = 0.25 * (u[i * sizex + (j - 1)] + // left u[i * sizex + (j + 1)] + // right u[(i - 1) * sizex + j] + // top u[(i + 1) * sizex + j]); // bottom } } for (j = 1; j < sizex - 1; j++) { for (i = 1; i < sizey - 1; i++) { u[i * sizex + j] = unew[i * sizex + j]; } } }


हम जैकोबी पुनरावृत्ति तब तक करते रहते हैं जब तक कि अवशिष्ट एक सीमा मान (लूप के अंदर) तक नहीं पहुंच जाता। अवशिष्ट गणना और सीमा मूल्यांकन इस फ़ंक्शन के बाहर किया जाता है और यहां चिंता का विषय नहीं है। तो, चलिए अब कमरे में हाथी के बारे में बात करते हैं!

आधार कोड कैसा कार्य करता है?

बिना किसी अनुकूलन (-O0) के, हमें निम्नलिखित परिणाम मिलते हैं:


बेस केस के लिए रनटाइम सेकंड में और एमएफएलओपी/एस ("-O0")


यहां, हम प्रदर्शन को एमएफएलओपी/एस के संदर्भ में मापते हैं। यही हमारी तुलना का आधार होगा.


एमएफएलओपी/एस का अर्थ है "मिलियन फ्लोटिंग पॉइंट ऑपरेशंस प्रति सेकंड।" यह माप की एक इकाई है जिसका उपयोग फ्लोटिंग-पॉइंट ऑपरेशन के संदर्भ में कंप्यूटर या प्रोसेसर के प्रदर्शन को मापने के लिए किया जाता है। फ़्लोटिंग-पॉइंट ऑपरेशंस में फ़्लोटिंग-पॉइंट प्रारूप में दर्शाए गए दशमलव या वास्तविक संख्याओं के साथ गणितीय गणना शामिल होती है।


एमएफएलओपी/एस का उपयोग अक्सर बेंचमार्क या प्रदर्शन मीट्रिक के रूप में किया जाता है, खासकर वैज्ञानिक और इंजीनियरिंग अनुप्रयोगों में जहां जटिल गणितीय गणना प्रचलित होती है। एमएफएलओपी/एस मान जितना अधिक होगा, सिस्टम या प्रोसेसर उतनी ही तेजी से फ्लोटिंग-पॉइंट ऑपरेशन करेगा।


नोट 1: एक स्थिर परिणाम प्रदान करने के लिए, मैं प्रत्येक रिज़ॉल्यूशन के लिए निष्पादन योग्य को 5 बार चलाता हूं और एमएफएलओपी/एस मानों का औसत मूल्य लेता हूं।

नोट 2: यह ध्यान रखना महत्वपूर्ण है कि Intel C++ कंपाइलर पर डिफ़ॉल्ट अनुकूलन -O2 है। इसलिए, स्रोत कोड संकलित करते समय -O0 निर्दिष्ट करना महत्वपूर्ण है।


आइए आगे बढ़ें और देखें कि अलग-अलग कंपाइलर फ़्लैग आज़माने पर ये रन टाइम कैसे अलग-अलग होंगे!

सबसे आम: -O1,-O2,-O3 और -Ofast

जब कोई कंपाइलर अनुकूलन के साथ शुरुआत करता है तो ये सबसे अधिक उपयोग किए जाने वाले कंपाइलर फ़्लैग में से कुछ हैं। आदर्श स्थिति में, Ofast > O3 > O2 > O1 > O0 का प्रदर्शन। हालाँकि, ऐसा जरूरी नहीं है. इन विकल्पों के महत्वपूर्ण बिंदु इस प्रकार हैं:


-O1:

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

-O2:

  • -O1 से अधिक संवर्द्धन:
    • वैश्वीकरण सक्षम करता है.
    • इंट्रिनिक्स की इनलाइनिंग और इंट्रा-फ़ाइल अंतरप्रक्रियात्मक अनुकूलन की अनुमति देता है।

-O3:

  • -O2 से अधिक संवर्द्धन:
    • अधिक आक्रामक लूप ट्रांसफ़ॉर्मेशन (फ़्यूज़न, ब्लॉक-अनरोल-एंड-जैम) सक्षम करता है।
    • यदि लूप और मेमोरी एक्सेस ट्रांसफ़ॉर्मेशन होते हैं तो ऑप्टिमाइज़ेशन लगातार -O2 से बेहतर प्रदर्शन कर सकता है। यह कोड को धीमा भी कर सकता है.
  • के लिए सिफारिश की:
    • लूप-हेवी फ़्लोटिंग-पॉइंट गणना और बड़े डेटा सेट वाले एप्लिकेशन।

-तेजी से:

  • निम्नलिखित झंडे सेट करता है:
    • "-O3"
    • "- नो-प्री-डिव" : यह अनुकूलन को सक्षम बनाता है जो पूर्ण आईईईई डिवीजन की तुलना में तेज़ और थोड़ा कम सटीक परिणाम देता है। उदाहरण के लिए, गणना गति में सुधार के लिए ए/बी की गणना ए * (1/बी) के रूप में की जाती है।
    • " -एफपी-मॉडल फास्ट=2" : अधिक आक्रामक फ़्लोटिंग-पॉइंट अनुकूलन सक्षम करता है।


आधिकारिक गाइड विस्तार से बताता है कि ये विकल्प वास्तव में कौन से अनुकूलन प्रदान करते हैं।


हमारे जैकोबी कोड पर इन विकल्पों का उपयोग करते समय, हमें ये निष्पादन रन समय प्राप्त होते हैं:

-झंडों की तुलना

यह स्पष्ट रूप से स्पष्ट है कि ये सभी अनुकूलन हमारे आधार कोड ("-O0" के साथ) से बहुत तेज़ हैं। निष्पादन रन समय बेस केस की तुलना में 2-3 गुना कम है। एमएफएलओपी/एस के बारे में क्या??


-झंडों की तुलना


खैर, यह कुछ बात है!!!


बेस केस के एमएफएलओपी/एस और अनुकूलन वाले एमएफएलओपी/एस के बीच एक बड़ा अंतर है।


कुल मिलाकर, हालांकि थोड़ा ही सही, "-O3" सबसे अच्छा प्रदर्शन करता है।


"- Ofast " (" -no-prec-div -fp-model fast=2 ") द्वारा उपयोग किए गए अतिरिक्त झंडे कोई अतिरिक्त गति नहीं दे रहे हैं।

आर्किटेक्चर लक्षित (-xHost,-xCORE-AVX512)

मशीन का आर्किटेक्चर कंपाइलर अनुकूलन को प्रभावित करने वाले एक महत्वपूर्ण कारक के रूप में सामने आता है। जब कंपाइलर उपलब्ध निर्देश सेट और हार्डवेयर द्वारा समर्थित अनुकूलन (जैसे वेक्टराइजेशन और SIMD) को जानता है तो यह प्रदर्शन को महत्वपूर्ण रूप से बढ़ा सकता है।


उदाहरण के लिए, मेरी स्काईलेक मशीन में 3 SIMD इकाइयाँ हैं: 1 AVX 512 और 2 AVX-2 इकाइयाँ।


क्या मैं सचमुच इस ज्ञान से कुछ कर सकता हूँ???


इसका उत्तर रणनीतिक संकलक झंडों में निहित है। " -xHost " और, अधिक सटीक रूप से, " -xCORE-AVX512 " जैसे विकल्पों के साथ प्रयोग करने से हमें मशीन की क्षमताओं की पूरी क्षमता का उपयोग करने और इष्टतम प्रदर्शन के लिए अनुकूलन करने की अनुमति मिल सकती है।


ये झंडे किस बारे में हैं इसका एक त्वरित विवरण यहां दिया गया है:


-एक्सहोस्ट:

  • लक्ष्य: निर्दिष्ट करता है कि कंपाइलर को होस्ट मशीन के उच्चतम निर्देश सेट के लिए अनुकूलित कोड उत्पन्न करना चाहिए।
  • प्रमुख विशेषताएँ: हार्डवेयर पर उपलब्ध नवीनतम सुविधाओं और क्षमताओं का लाभ उठाता है। यह लक्ष्य प्रणाली पर अद्भुत गति प्रदान कर सकता है।
  • विचार: हालांकि यह ध्वज होस्ट आर्किटेक्चर के लिए अनुकूलित है, इसके परिणामस्वरूप ऐसे बायनेरिज़ हो सकते हैं जो अलग-अलग निर्देश सेट आर्किटेक्चर के साथ विभिन्न मशीनों में पोर्टेबल नहीं हैं।

-xCORE-AVX512:

  • लक्ष्य: कंपाइलर को इंटेल एडवांस्ड वेक्टर एक्सटेंशन्स 512 (एवीएक्स-512) इंस्ट्रक्शन सेट का उपयोग करने वाले कोड को उत्पन्न करने के लिए स्पष्ट रूप से निर्देश दें।

  • मुख्य विशेषताएं: AVX-512 एक उन्नत SIMD (सिंगल इंस्ट्रक्शन, मल्टीपल डेटा) इंस्ट्रक्शन सेट है जो AVX2 जैसे पिछले संस्करणों की तुलना में व्यापक वेक्टर रजिस्टर और अतिरिक्त संचालन प्रदान करता है। इस फ़्लैग को सक्षम करने से कंपाइलर अनुकूलित प्रदर्शन के लिए इन उन्नत सुविधाओं का लाभ उठा सकता है।

  • विचार: पोर्टेबिलिटी फिर से यहाँ अपराधी है। AVX-512 निर्देशों के साथ उत्पन्न बायनेरिज़ उन प्रोसेसर पर बेहतर ढंग से नहीं चल सकती हैं जो इस निर्देश सेट का समर्थन नहीं करते हैं। हो सकता है कि वे बिल्कुल भी काम न करें!


AVX-512 सेट निर्देश Zmm रजिस्टरों का उपयोग करते हैं, जो 512-बिट विस्तृत रजिस्टरों का एक सेट है। ये रजिस्टर वेक्टर प्रोसेसिंग के लिए आधार के रूप में काम करते हैं।


डिफ़ॉल्ट रूप से, " -xCORE-AVX512 " मानता है कि प्रोग्राम को zmm रजिस्टरों के उपयोग से कोई लाभ नहीं होगा। कंपाइलर zmm रजिस्टरों का उपयोग करने से बचता है जब तक कि प्रदर्शन लाभ की गारंटी न हो।


यदि कोई बिना किसी प्रतिबंध के zmm रजिस्टरों का उपयोग करने की योजना बना रहा है, तो " -qopt-zmm-usage " को उच्च पर सेट किया जा सकता है। हम भी यही करेंगे.


विस्तृत निर्देशों के लिए आधिकारिक मार्गदर्शिका देखना न भूलें।


आइए देखें कि ये झंडे हमारे कोड के लिए कैसे काम करते हैं:

-xHost और -xCORE-AVX512 के प्रभाव

वू हू!


अब हम सबसे छोटे रिज़ॉल्यूशन के लिए 1200 एमएफएलओपी/एस का आंकड़ा पार कर गए हैं। अन्य संकल्पों के लिए एमएफएलओपी/एस मूल्यों में भी वृद्धि हुई है।


उल्लेखनीय बात यह है कि हमने इन परिणामों को बिना किसी महत्वपूर्ण मैन्युअल हस्तक्षेप के प्राप्त किया है - बस एप्लिकेशन संकलन प्रक्रिया के दौरान मुट्ठी भर कंपाइलर फ़्लैग को शामिल करके।


हालाँकि, यह उजागर करना आवश्यक है कि संकलित निष्पादन योग्य केवल उसी निर्देश सेट का उपयोग करने वाली मशीन के साथ संगत होगा।


अनुकूलन-बनाम-पोर्टेबिलिटी व्यापार-बंद स्पष्ट है, क्योंकि किसी विशेष निर्देश सेट के लिए अनुकूलित कोड विभिन्न हार्डवेयर कॉन्फ़िगरेशन में पोर्टेबिलिटी का त्याग कर सकता है। तो, सुनिश्चित करें कि आप जानते हैं कि आप क्या कर रहे हैं!!


नोट: यदि आपका हार्डवेयर AVX-512 का समर्थन नहीं करता है तो चिंता न करें। Intel C++ कंपाइलर AVX, AVX-2 और यहां तक कि SSE के लिए अनुकूलन का समर्थन करता है। दस्तावेज़ में वह सब कुछ है जो आपको जानना आवश्यक है!

अंतरप्रक्रियात्मक अनुकूलन (आईपीओ)

अंतरप्रक्रियात्मक अनुकूलन में व्यक्तिगत कार्यों के दायरे से परे देखते हुए, कई कार्यों या प्रक्रियाओं में कोड का विश्लेषण और परिवर्तन शामिल है।


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


इंटेल कंपाइलर दो सामान्य प्रकार के आईपीओ का समर्थन करता है: एकल-फ़ाइल संकलन और बहु-फ़ाइल संकलन (संपूर्ण प्रोग्राम अनुकूलन) [ 3 ]। उनमें से प्रत्येक का प्रदर्शन करने वाले दो सामान्य कंपाइलर फ़्लैग हैं:


-आईपीओ:

  • लक्ष्य: अंतरप्रक्रियात्मक अनुकूलन को सक्षम बनाता है, जिससे कंपाइलर को संकलन के दौरान व्यक्तिगत स्रोत फ़ाइलों से परे, पूरे प्रोग्राम का विश्लेषण और अनुकूलन करने की अनुमति मिलती है।

  • मुख्य विशेषताएं: - संपूर्ण प्रोग्राम अनुकूलन: " -आईपीओ " पूरे कार्यक्रम में कार्यों और प्रक्रियाओं के बीच बातचीत पर विचार करते हुए, सभी स्रोत फ़ाइलों में विश्लेषण और अनुकूलन करता है। - क्रॉस-फ़ंक्शन और क्रॉस-मॉड्यूल अनुकूलन: ध्वज इनलाइनिंग फ़ंक्शंस, सिंक्रनाइज़ेशन की सुविधा देता है विभिन्न प्रोग्राम भागों में अनुकूलन और डेटा प्रवाह विश्लेषण।

  • विचार: इसके लिए एक अलग लिंक चरण की आवश्यकता है। " -ipo " के साथ संकलन करने के बाद, अंतिम निष्पादन योग्य उत्पन्न करने के लिए एक विशेष लिंक चरण की आवश्यकता होती है। कंपाइलर लिंकिंग के दौरान संपूर्ण प्रोग्राम दृश्य के आधार पर अतिरिक्त अनुकूलन करता है।


-आईपी:

  • लक्ष्य: अंतरप्रक्रियात्मक विश्लेषण-प्रसार को सक्षम बनाता है, जिससे कंपाइलर को अलग लिंक चरण की आवश्यकता के बिना कुछ अंतरप्रक्रियात्मक अनुकूलन करने की अनुमति मिलती है।

  • मुख्य विशेषताएं:- विश्लेषण और प्रसार: " -आईपी " कंपाइलर को संकलन के दौरान विभिन्न कार्यों और मॉड्यूल में अनुसंधान और डेटा प्रसार करने में सक्षम बनाता है। हालाँकि, यह उन सभी अनुकूलन को निष्पादित नहीं करता है जिनके लिए पूर्ण प्रोग्राम दृश्य की आवश्यकता होती है। - तेज़ संकलन: " -ipo " के विपरीत, " -ip " के लिए एक अलग लिंकिंग चरण की आवश्यकता नहीं होती है, जिसके परिणामस्वरूप त्वरित संकलन समय होता है। यह विकास के दौरान फायदेमंद हो सकता है जब त्वरित प्रतिक्रिया आवश्यक हो।

  • विचार: फ़ंक्शन इनलाइनिंग सहित केवल कुछ सीमित अंतरप्रक्रियात्मक अनुकूलन होते हैं।


-आईपीओ आम तौर पर अधिक व्यापक अंतरप्रक्रियात्मक अनुकूलन क्षमताएं प्रदान करता है क्योंकि इसमें एक अलग लिंक चरण शामिल होता है लेकिन लंबे संकलन समय की कीमत पर आता है। [ 4 ]

-आईपी एक तेज़ विकल्प है जो अलग लिंक चरण की आवश्यकता के बिना कुछ अंतरप्रक्रियात्मक अनुकूलन करता है, जो इसे विकास और परीक्षण चरणों के लिए उपयुक्त बनाता है। [ 5 ]


चूँकि हम केवल प्रदर्शन और विभिन्न अनुकूलन, संकलन समय या निष्पादन योग्य के आकार के बारे में बात कर रहे हैं, यह हमारी चिंता का विषय नहीं है, हम " -ipo " पर ध्यान केंद्रित करेंगे।

-आईपीओ का प्रभाव

-fno-उपनाम

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


आइए फिर से हमारे कोड पर एक नज़र डालें:


 /* * One Jacobi iteration step */ void jacobi(double *u, double *unew, unsigned sizex, unsigned sizey) { int i, j; for (j = 1; j < sizex - 1; j++) { for (i = 1; i < sizey - 1; i++) { unew[i * sizex + j] = 0.25 * (u[i * sizex + (j - 1)] + // left u[i * sizex + (j + 1)] + // right u[(i - 1) * sizex + j] + // top u[(i + 1) * sizex + j]); // bottom } } for (j = 1; j < sizex - 1; j++) { for (i = 1; i < sizey - 1; i++) { u[i * sizex + j] = unew[i * sizex + j]; } } }


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


क्यों??


यू का उपयोग करके यून्यू की गणना करने की अभिव्यक्ति में 4 पड़ोसी यू मानों का औसत शामिल है। यदि आप और यून्यू दोनों एक ही स्थान की ओर इशारा करें तो क्या होगा? यह उपनाम सूचकों की शास्त्रीय समस्या बन जाएगी [ 7 ]।


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


हमारे मामले में, हम जानते हैं कि यू और यून्यू अलग-अलग मेमोरी स्थान हैं और अलग-अलग मान संग्रहीत करने के लिए हैं। इसलिए, हम कंपाइलर को आसानी से बता सकते हैं कि यहां कोई उपनाम नहीं होगा।


हम इसे कैसे करते हैं?


दो विधियाँ हैं. पहला है C “ प्रतिबंधित ” कीवर्ड । लेकिन इसके लिए कोड बदलने की आवश्यकता है। फिलहाल हम ऐसा नहीं चाहते.


कुछ भी सरल? आइए " -fno-alias " का प्रयास करें।


-fno-उपनाम:

  • लक्ष्य: कंपाइलर को प्रोग्राम में अलियासिंग न मानने का निर्देश दें।

  • मुख्य विशेषताएं: यह मानते हुए कि कोई अलियासिंग नहीं है, कंपाइलर अधिक स्वतंत्र रूप से कोड को अनुकूलित कर सकता है, संभावित रूप से प्रदर्शन में सुधार कर सकता है।

  • विचार: डेवलपर को इस ध्वज का उपयोग करने में सावधानी बरतनी होगी क्योंकि किसी भी अनुचित उपनाम के मामले में, प्रोग्राम अप्रत्याशित आउटपुट दे सकता है।


अधिक विवरण आधिकारिक दस्तावेज़ में पाया जा सकता है।


यह हमारे कोड के लिए कैसा प्रदर्शन करता है?

-fno-उपनाम का प्रभाव

खैर, अब हमारे पास कुछ है!!!


हमने यहां उल्लेखनीय गति हासिल की है, जो पिछले अनुकूलन से लगभग तीन गुना अधिक है। इस बढ़ोतरी के पीछे क्या रहस्य है?


कंपाइलर को अलियासिंग न मानने का निर्देश देकर, हमने इसे शक्तिशाली लूप अनुकूलन जारी करने की स्वतंत्रता दी है।


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

अंतिम रेखांकन

इस प्रकार सभी अनुकूलन एक-दूसरे के विरुद्ध प्रदर्शन करते हैं:


सभी अनुकूलन झंडों की तुलना

कंपाइलर अनुकूलन रिपोर्ट (-qopt-रिपोर्ट)

Intel C++ कंपाइलर एक मूल्यवान सुविधा प्रदान करता है जो उपयोगकर्ताओं को अनुकूलन उद्देश्यों के लिए किए गए सभी समायोजनों का सारांश देते हुए एक अनुकूलन रिपोर्ट तैयार करने की अनुमति देता है [ 8 ]। यह व्यापक रिपोर्ट YAML फ़ाइल स्वरूप में सहेजी गई है, जो कोड के भीतर कंपाइलर द्वारा लागू अनुकूलन की एक विस्तृत सूची प्रस्तुत करती है। विस्तृत विवरण के लिए, " -qopt-रिपोर्ट " पर आधिकारिक दस्तावेज़ देखें।

आगे क्या?

हमने मुट्ठी भर कंपाइलर फ़्लैग पर चर्चा की जो वास्तव में हमारे द्वारा कुछ किए बिना हमारे कोड के प्रदर्शन में काफी सुधार कर सकते हैं। एकमात्र शर्त: आँख मूँद कर कुछ भी न करें; सुनिश्चित करें कि आप जानते हैं कि आप क्या कर रहे हैं!!


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


इन कंपाइलर फ़्लैग के अलावा, वेक्टराइज़ेशन, SIMD इंट्रिनिक्स, प्रोफ़ाइल गाइडेड ऑप्टिमाइज़ेशन और गाइडेड ऑटो पैरेललिज़्म जैसी तकनीकों का एक पूरा समूह है, जो आपके कोड के प्रदर्शन को आश्चर्यजनक रूप से बेहतर बना सकता है।


इसी तरह, Intel C++ कंपाइलर (और सभी लोकप्रिय कंपाइलर) भी Pragma निर्देशों का समर्थन करते हैं, जो बहुत अच्छी विशेषताएं हैं। इंटेल-स्पेसिफिक प्राग्मा रेफरेंस पर कुछ प्राग्मा जैसे आईवीडीईपी, पैरेलल, सिमड, वेक्टर इत्यादि की जांच करना उचित है।


Giphy पर बस यही सब लोग हैं

सुझाए गए पाठ

[1] अनुकूलन और प्रोग्रामिंग (intel.com)

[2] कैसरस्लॉटर्न-लैंडौ विश्वविद्यालय में "एल्वेट्रिट्स्च" के साथ उच्च प्रदर्शन कंप्यूटिंग (rptu.de)

[3] अंतरप्रक्रियात्मक अनुकूलन (intel.com)

[4] आईपीओ, क्यूइपो (इंटेल.कॉम)

[5] आईपी, क्यूआईपी (इंटेल.कॉम)

[6] SPEChpc द्वारा उपयोग के लिए इंटेल कंपाइलर, ऑप्टिमाइज़ेशन और अन्य फ़्लैग

[7] अलियासिंग - आईबीएम दस्तावेज़ीकरण

[8] Intel® कंपाइलर ऑप्टिमाइज़ेशन रिपोर्ट


अनस्प्लैश पर इगोर ओमिलाव द्वारा प्रदर्शित फोटो।


यहाँ भी प्रकाशित किया गया है.