क्या कॉन्स्टीट्यूशन से प्रदर्शन में सुधार हो सकता है?


92

मैंने कई बार पढ़ा है कि आपके C या C ++ कोड में कॉन्स्टेंस-शुद्धता को लागू करना न केवल स्थिरता के संबंध में एक अच्छा अभ्यास है, बल्कि यह आपके कंपाइलर को भी अनुकूलन करने की अनुमति दे सकता है। हालाँकि, मैंने पूरा विपरीत पढ़ा है, - यह कि यह प्रदर्शन को बिल्कुल प्रभावित नहीं करता है।

इसलिए, क्या आपके पास ऐसे उदाहरण हैं जहां आपके कार्यक्रम के प्रदर्शन को बेहतर बनाने के साथ कॉन्स्ट शुद्धता आपके कंपाइलर की सहायता कर सकती है?


50
स्थिरता के संबंध में कॉन्स्ट-शुद्धता सबसे अच्छी प्रथाओं में से एक है। यदि आपका C ++ कोड कॉन्स्टेबल-सही नहीं है, तो यह मूल रूप से बकवास का ढेर है, जो आपदा के लिए इंतजार कर रहा है। यह प्रदर्शन को प्रभावित करने का इरादा नहीं है।

2
@ नील बटरवर्थ: दुर्भाग्य से उलटा सच नहीं है।
बीटा

6
यहां एक उदाहरण constदिया गया है जहां प्रदर्शन में अंतर आया है: stackoverflow.com/questions/1121791/… । यह अनिवार्य रूप से एक गुणवत्ता-कार्यान्वयन का मुद्दा था, हालांकि। constयह निर्धारित नहीं किया गया कि कंपाइलर कानूनी रूप से अनुकूलन कर सकता है या नहीं , बस यह हुआ कि कंपाइलर का संस्करण गायब होने पर उसे बनाने में विफल रहा।
स्टीव जेसप

3
मुझे पूरा यकीन है कि "morgennebel" पहले वाक्य में एक 'केवल' से चूक गया था: यह "केवल एक अच्छा अभ्यास नहीं है" के साथ बहुत अधिक समझ में आता है।
इनाह

2
@ इयान हां, मैंने इस पर विचार किया। लेकिन ओपी के पास स्पष्ट करने का पर्याप्त समय है। मैं वास्तव में लोगों से चिढ़ जाता हूं जो प्रश्न पोस्ट करते हैं और फिर बस गायब हो जाते हैं।

जवाबों:


77

constशुद्धता के प्रदर्शन में सुधार नहीं कर सकते क्योंकि const_castऔर mutableभाषा में हैं, और conformingly नियमों को तोड़ने के कोड अनुमति देते हैं। यह C ++ 11 में और भी खराब हो जाता है, जहां आपका constडेटा उदाहरण के लिए एक सूचक हो सकता है std::atomic, जिसका अर्थ है कि संकलक को अन्य थ्रेड द्वारा किए गए परिवर्तनों का सम्मान करना होगा।

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

यह सब कहा, constशुद्धता बनाए रखने के संबंध में शुद्धता एक अच्छी बात है। अन्यथा, आपके वर्ग के ग्राहक उस वर्ग के आंतरिक सदस्यों को तोड़ सकते हैं। उदाहरण के लिए, मानक पर विचार करें std::string::c_str()- यदि यह एक स्थिर मूल्य नहीं लौटा सकता है, तो आप स्ट्रिंग के आंतरिक बफर के साथ चारों ओर पेंच करने में सक्षम होंगे!

constप्रदर्शन कारणों से उपयोग न करें । स्थिरता के कारणों के लिए इसका उपयोग करें।


31
"आप स्ट्रिंग के आंतरिक बफर के साथ चारों ओर पेंच करने में सक्षम होंगे!" - महत्वपूर्ण रूप से, आप गलती से आंतरिक बफर के साथ चारों ओर पेंच करने में सक्षम होंगे । संकलक के कारण कंपाइलर त्रुटियां constहैं, कह रही है, "आप कुछ बेवकूफ कर रहे हैं"।
स्टीव जेसप

4
... और कॉन्स्ट-कास्ट्स ये कहते हुए साइनपोस्ट हैं, "इस कोड के लेखक कुछ चतुर करने की कोशिश कर रहे हैं" ;-)
स्टीव जेसोप

5
@Steve Jessop - या कॉन्स्ट-कास्ट यह कहते हुए साइनपोस्ट हैं कि "मैं एक कांस्ट-सही गुच्छा को एक नॉन-कॉस्ट-सही करने के लिए कोड करने की कोशिश कर रहा हूं, और मैं एक को भी ठीक नहीं कर सकता"। जो, आपको बता दें, किसी भी तरह से चतुर नहीं है, बस कष्टप्रद है।
माइकल कोहेन

7
@ मिचेल - हाँ, उचित बिंदु। शायद मूल साइनपोस्ट "आप कुछ बेवकूफ बना रहे हैं" नहीं है, बल्कि "किसी का कुछ बेवकूफ कर रहा है"।
स्टीव जेसप op

गॉडबोल्ट और अर्डुइनो ने मुझे बताया कि कॉन्स्ट शुद्धता केवल मनोरंजन के लिए नहीं है।
dgrat

31

हाँ यह कर सकते हैं।

अधिकांश consts पूरी तरह से प्रोग्रामर के लाभ के लिए हैं और कंपाइलर को ऑप्टिमाइज़ करने में मदद नहीं करते हैं क्योंकि यह उन्हें हटाने के लिए कानूनी है और इसलिए वे कंपाइलर को अनुकूलन के लिए उपयोगी कुछ भी नहीं बताते हैं। हालांकि, कुछ constएस (कानूनी रूप से) दूर नहीं हो सकते हैं और ये कंपाइलर को अनुकूलन के लिए उपयोगी जानकारी प्रदान करते हैं।

एक उदाहरण के रूप में, एक constप्रकार के साथ परिभाषित वैश्विक वैरिएबल तक पहुंच को इनलाइन किया जा सकता है, जबकि एक constप्रकार के बिना एक इनबिल्ट नहीं किया जा सकता है क्योंकि यह रनटाइम में बदल सकता है।

https://godbolt.org/g/UEX4NB

सी ++:

int foo1 = 1;
const int foo2 = 2;

int get_foo1() {
    return foo1;
}

int get_foo2() {
    return foo2;
}

एएसएम:

foo1:
        .long   1
foo2:
        .long   2
get_foo1():
        push    rbp
        mov     rbp, rsp
        mov     eax, DWORD PTR foo1[rip] ; foo1 must be accessed by address
        pop     rbp
        ret
get_foo2():
        push    rbp
        mov     rbp, rsp
        mov     eax, 2 ; foo2 has been replaced with an immediate 2
        pop     rbp
        ret

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


स्टीव जेसप मूल प्रश्न पर अपनी टिप्पणी में एक और उदाहरण देते हैं जो कुछ उल्लेख करने लायक है। ब्लॉक स्कोप में, कंपाइलर के लिए यह सुनिश्चित करना संभव है कि अगर कोई वैरिएबल म्यूट किया जाएगा और उसी के अनुसार ऑप्टिमाइज़ किया जाएगा const, क्योंकि कंपाइलर वेरिएबल के सभी उपयोगों को देख सकता है। इसके विपरीत, ऊपर के उदाहरण में, यह भविष्यवाणी करना असंभव है कि क्या foo1इसे अन्य अनुवाद इकाइयों में संशोधित किया जा सकता है। मुझे लगता है कि एक काल्पनिक भावुक अल्ट्रा-कंपाइलर एक पूरे कार्यक्रम का विश्लेषण कर सकता है और यह निर्धारित कर सकता है कि क्या यह इनलाइन एक्सेस के लिए वैध है foo1... लेकिन असली कंपाइलर नहीं कर सकते।


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

1
@Acorn यहां एक ही उदाहरण है, लेकिन एक क्लास ऑब्जेक्ट के साथ: godbolt.org/z/R-Zfgc । इसके अलावा, उदाहरण में चर में बाहरी संबंध हैं।
प्रिक्सोलिटिक

6

मेरे अनुभव में, नहीं

स्केलर चर के लिए, संकलक यह निर्धारित करने में सक्षम है कि जब भी मूल्य बदल जाए और स्वयं आवश्यक अनुकूलन करें।

एरे पॉइंटर्स के लिए, कांस्ट शुद्धता इस बात की गारंटी नहीं है कि संभावित अलियासिंग समस्याओं की उपस्थिति में मूल्य वास्तव में स्थिर हैं। इसलिए कंपाइलर ऑप्टिमाइज़ेशन करने के लिए अकेले कॉन्स्ट संशोधक का उपयोग नहीं कर सकते हैं

यदि आप अनुकूलन देख रहे हैं, तो आपको विचार करना चाहिए __restrict__या विशेष फ़ंक्शन संशोधक / विशेषताएँ: http://gcc.gnu.org/onbuildocs/gcc/Function-Attributes.html


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.