"संभावना" और "संभावनाहीन" मैक्रोज़ का कितना उपयोग बहुत अधिक है?


12

अक्सर likelyऔर unlikelyमैक्रोज़ के रूप में जाना जाता है यह संकलक को यह जानने में मदद करता है कि क्या ifआमतौर पर प्रवेश किया जा रहा है या छोड़ दिया गया है। इसका उपयोग करने से कुछ (बल्कि मामूली) प्रदर्शन में सुधार होता है।

मैंने हाल ही में उनका उपयोग करना शुरू कर दिया है, और मुझे यकीन नहीं है कि इस तरह के संकेतों का कितनी बार उपयोग किया जाना चाहिए। वर्तमान में मैं इसे एरर चेकिंग ifएस के साथ उपयोग करता हूं , जो आमतौर पर चिह्नित होते हैं unlikely। उदाहरण के लिए:

mem = malloc(size);
if (unlikely(mem == NULL))
  goto exit_no_mem;

यह ठीक लगता है, लेकिन त्रुटि-जाँच ifबहुत बार होती है और परिणामस्वरूप उक्त मैक्रोज़ का उपयोग होता है।

मेरा प्रश्न यह है कि क्या प्रत्येक त्रुटि जाँच पर मैक्रो likelyऔर unlikelyमैक्रो होना बहुत अधिक है if?

जब हम इस पर होते हैं, तो वे किन अन्य स्थानों पर अक्सर उपयोग किए जाते हैं?


मेरे वर्तमान उपयोग में यह एक पुस्तकालय में है जो वास्तविक समय के सबसिस्टम से एक अमूर्त बनाता है, इसलिए कार्यक्रम RTAI, QNX और अन्य के बीच पोर्टेबल हो जाएंगे। उस ने कहा, अधिकांश कार्य छोटे होते हैं और सीधे एक या दो अन्य कार्यों को कहते हैं। कई static inlineकार्य भी हैं।

इसलिए, सबसे पहले, यह एक ऐसा एप्लिकेशन नहीं है जिसे मैं प्रोफाइल कर सकता हूं। यह "बोतल-गर्दन की पहचान" करने का कोई मतलब नहीं है क्योंकि यह एक पुस्तकालय है, एक स्टैंडअलोन एप्लिकेशन नहीं है।

दूसरा, यह इस तरह का है "मुझे पता है कि यह संभावना नहीं है, मैं इसे कंपाइलर को भी बता सकता हूं"। मैं सक्रिय रूप से अनुकूलित करने का प्रयास नहीं करता हूं if


7
माइक्रो का अनुकूलन मेरे लिए ...
शाफ़्ट सनकी

2
एप्लिकेशन कोड के लिए, मैं उन्हें केवल तभी जोड़ूंगा जब प्रोफाइलिंग से पता चले कि इस कोड का उपयोग गर्म रास्ते में किया गया है।
कोडइन्चौस


@ नाम, कि बस कहते हैं likelyऔर unlikelyमौजूद हैं और वे क्या करते हैं। मुझे ऐसा कुछ नहीं मिला जो वास्तव में सुझाव दे कि कब और कहाँ उनका उपयोग करना सबसे अच्छा है।
शहबाज

@ शहबाज "यदि स्थिति अक्सर झूठी होती है, तो निष्पादन रैखिक नहीं होता है। बीच में अप्रयुक्त कोड का एक बड़ा हिस्सा होता है जो न केवल पूर्ववर्ती के कारण एल 1 आई को प्रदूषित करता है, बल्कि यह शाखा की भविष्यवाणी के कारण भी समस्या पैदा कर सकता है। यदि शाखा की भविष्यवाणी गलत है कि सशर्त अभिव्यक्ति बहुत अक्षम हो सकती है। " तो, तंग छोरों जहां आप सुनिश्चित करना चाहते हैं कि आपके लिए आवश्यक निर्देश L1i कैश में हैं
James

जवाबों:


12

क्या आपको उस प्रदर्शन की आवश्यकता है जो बुरी तरह से आप उस के साथ अपने कोड को प्रदूषित करने के लिए तैयार हैं? यह एक मामूली अनुकूलन है।

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

जब तक आप yesउपरोक्त सभी का जवाब नहीं दे सकते, तब तक सामान के साथ परेशान न करें।

संपादित करें: संपादन के जवाब में। जब आप प्रोफ़ाइल नहीं कर सकते, तब भी आप आमतौर पर हॉटस्पॉट का अनुमान लगा सकते हैं। एक मेमोरी आवंटन फ़ंक्शन जिसे सभी द्वारा बुलाया जाता है, एक अच्छा उम्मीदवार है, खासकर जब से पूरे पुस्तकालय के लिए काम करने के लिए मैक्रो के केवल एक ही उपयोग की आवश्यकता होती है।


1
बस स्पष्ट होने के लिए, मैंने आपको वोट नहीं दिया। हालाँकि, आपका उत्तर वास्तव में मेरे प्रश्न का उत्तर नहीं देता है। क्या आप यह कहना चाह रहे हैं कि (un)likelyमैक्रो का उपयोग शायद ही कभी किया जाता है और केवल अत्यंत प्रदर्शन क्रिटिकल कोड में? क्या अक्सर इसका उपयोग करना "बुरा व्यवहार" है, या सिर्फ "अनावश्यक" है?
शहबाज

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

3
@Peter: हालांकि यह बहुत बुरा है कि वाक्यविन्यास अच्छा नहीं है, इस बात की संभावना या संभावना नहीं है कि कोड पढ़ने वाले मनुष्यों को उपयोगी जानकारी मिल सकती है । उदाहरण के लिए, किसी ने जो देखा if (likely(x==2 || x==3)) doOneThing(); else switch(x) { ... }, ifवह मान सकता है कि प्रोग्रामर का मान 2 और 3 के लिए प्रोग्रामर का उपयोग केवल प्रोग्रामर के परिणाम के बारे में नहीं था, यह न जानते हुए कि सी caseएक सिंगल हैंडलर के साथ दो लेबल जोड़ सकता है ।
सुपरकैट

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

2

यदि आप x86 / x64 (और 20-वर्षीय CPU का उपयोग नहीं कर रहे हैं) के लिए लिख रहे हैं, तो __builtin_expect () का उपयोग करने से प्रदर्शन लाभ नगण्य होगा। इसका कारण यह है कि आधुनिक x86 / x64 सीपीयू (हालांकि एटम के बारे में 100% निश्चित नहीं है), गतिशील शाखा भविष्यवाणी है, इसलिए आवश्यक रूप से सीपीयू उस शाखा के बारे में "सीखता है" जो अक्सर लिया जाता है। निश्चित रूप से, यह जानकारी केवल सीमित शाखाओं के लिए संग्रहीत की जा सकती है, हालांकि, केवल दो ही मामले संभव हैं। यदि (ए) यह "अक्सर उपयोग की जाने वाली" शाखा है, तो आपके कार्यक्रम को उस गतिशील शाखा की भविष्यवाणी से लाभ होगा, और अगर (बी) यह "दुर्लभ" शाखा है, तो आप वास्तव में किसी भी यथार्थवादी प्रदर्शन को गलतफहमी के कारण हिट नहीं देखेंगे ऐसी दुर्लभ शाखाएँ (शाखा बदमाशियों के 20 सीपीयू चक्र TOO खराब नहीं होते हैं यदि यह नीले चंद्रमा में एक बार होता है)।

नायब: इसका मतलब यह नहीं है कि आधुनिक x86 / x64 पर शाखा के दुरुपयोग का महत्व कम हो गया है: कूद-नोजंप की 50-50 संभावना वाली कोई भी शाखा अभी भी एक दंड (IIRC 10-20 सीपीयू चक्र) भोगेगी, इसलिए आंतरिक लूप शाखाओं में हो सकती है अभी भी बचने की जरूरत है। यह x86 / x64 पर __builtin_expect () का महत्व है जो कम हो गया है (IIRC, लगभग 10-15 साल पहले या तो) - ज्यादातर गतिशील शाखा भविष्यवाणी के कारण।

NB2: x86 / x64, YMMV से परे अन्य प्लेटफार्मों के लिए।


खैर, कंपाइलर जानता है कि सीपीयू किस शाखा में कम होने की उम्मीद करेगा। और यह उसके लिए व्यवस्था कर सकता है कि वास्तव में संभावना नहीं है। लेकिन कंपाइलर शायद पहले से ही उस पैटर्न को नहीं जानता है unlikely
डेडुप्लिकेटर

@Deduplicator: डायनेमिक ब्रांच प्रेडिक्शन के साथ, कंपाइलर को यह पता नहीं होता कि कौन सी ब्रांच की संभावना अधिक है क्योंकि सीपीयू इसे रनटाइम के आधार पर कोड में इस बहुत ही पॉइंट के माध्यम से पिछले रनों के आधार पर गणना करता है।
No-Bugs Hare
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.