2010-11-10 11 views
12

यह 64 बिट इंट्स के बारे में एक दक्षता प्रश्न है। मान लीजिए कि मुझे "int" पैरामीटर के मान को संशोधित करने की आवश्यकता नहीं है, क्या मुझे इसे मूल्य या संदर्भ से पास करना चाहिए।सी ++ 64 बिट int: संदर्भ द्वारा पास या मूल्य

मान लिया जाये कि 32 बिट मशीन:

1) 32 बिट पूर्णांक: मुझे लगता है कि जवाब "मूल्य से गुजरती हैं" जैसा है "संदर्भ से गुजरती हैं" अतिरिक्त स्मृति देखने की भूमि के ऊपर होगा।

2) 64 बिट int: यदि मैं संदर्भ से गुजरता हूं, तो मैं केवल स्टैक पर 32 बिट पता पास करता हूं, लेकिन अतिरिक्त मेमोरी लुकअप की आवश्यकता होती है। तो उनमें से कौन सा बेहतर (संदर्भ या मूल्य) है?

यदि मशीन 64 बिट है तो क्या होगा? क्योंकि यह एक रजिस्टर मूल्य के रूप में पारित किया जा सकता

संबंध है,

जेपी

+3

"दक्षता" :(KISS। आप इसे हर दूसरे खूनी पूर्णांक को कैसे पारित करते हैं। –

+0

संकलक शायद इसे किसी भी तरह से अनुकूलित करेगा। –

+0

@pst: मजेदार टिप्पणी के लिए +1। आदमी मैं बहुत कठिन हँसे। –

उत्तर

10

मूल्य से गुजरें - निश्चित रूप से। यदि सिस्टम 64-बिट है तो इसका मतलब है कि यह 64-बिट शब्द को बहुत तेज़ी से कॉपी करता है।

8

यहां तक ​​कि मूल्य से एक 64 बिट मशीन पास पर बेहतर है (कुछ बहुत कुछ अपवादों के साथ),।

+7

मैं कहूंगा * खासकर * 64-बिट मशीन पर। – cHao

+0

तो 64-बिट int "मूल्य से" गुजरना अधिक कुशल है जो 32-बिट या 64-बिट मशीनों पर 64-बिट int "संदर्भ द्वारा" पास कर रहा है, (64-बिट मशीनों पर भी अधिक), है ना? –

+0

मुझे अपवादों को जानने के लिए उत्सुकता है (यह चर्चा के दायरे से बाहर नहीं है :) –

4

तर्क के लिए, मतभेदों को हटाने वाले ऑप्टिमाइज़र के मामूली मामले को अनदेखा करते हैं। आइए यह भी कहें कि आप माइक्रोसॉफ्ट के इंटेल 64-बिट कॉलिंग कन्वेंशन (जो कि लिनक्स एबीआई से अलग हैं) का उपयोग कर रहे हैं, तो आपको स्टैक पर धक्का देने से पहले ऐसे मूल्यों को पारित करने के लिए आपके पास 4 64-बिट रजिस्ट्रार हैं। यह स्पष्ट रूप से बेहतर है।

32-बिट ऐप के लिए, मूल्य से और वे सीधे ढेर पर जाएंगे। संदर्भ के बजाय एक रजिस्टर में एक सूचक डाल सकते हैं (फिर से, स्टैक का उपयोग करने से पहले ऐसे कुछ रजिस्टर उपयोगों की अनुमति है)। हम इस कुछ स्थिरांक संदर्भ द्वारा मूल्य और f2 (101) द्वारा ग्राम ++ -O3 -S से उत्पादन, बुला f1 (99) में कर सकते हैं:

void f1(int64_t); 
void f2(const int64_t&); 

int main() 
{ 
    f1(99); 
    f2(101); 
} 

... 

    pushl 0 
    pushl $99 
    call _Z2f1x // by value - pushed two halves to stack 

    leal -8(%ebp), %eax 
    movl %eax, (%esp) 
    movl $101, -8(%ebp) 
    movl $0, -4(%ebp) 
    call _Z2f2RKx // by const& - ugly isn't it!?! 

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

pst की सलाह के लिए एक नोड ...

"दक्षता" :(KISS इसे पारित कैसे आप हर दूसरे खूनी पूर्णांक पास -।। Pst

... हालांकि, कभी कभी आप टेम्पलेट को KISS लागू मापदंडों और उन सब को स्थिरांक टी & भले ही कुछ रजिस्टरों में फिट हो सकता बनाने ....

7

उन्हें एक boost::call_traits<int64_t>::param_type के रूप में उत्तीर्ण। इस टेम्पलेट समर्थित प्लेटफार्मों पर किसी भी प्रकार के पारित करने के लिए सर्वोत्तम प्रथाओं कैप्चर करता है। इसलिए, यह अलग होगा 32 और 64 बिट प्लेटफार्मों पर, लेकिन आप हर जगह एक ही कोड का उपयोग कर सकते हैं। यह भी काम करता है I अन्य टेम्पलेट्स जहां आप अभी तक सटीक प्रकार नहीं जानते हैं।

+10

+1 यह पूर्णांक के उत्थान को अनुकूलित करने के बारे में चिंतित लोगों के लिए सबसे अच्छी सजा है, कि उन्हें बहुत कुछ टाइप करना होगा। –

+0

शायद यह सच है कि 64 बिट डेटा के लिए अंतर नगण्य है। हालांकि, सवाल की भावना सार्थक आईएमओ है। अगर मेरे पास 12 बाइट संरचना है तो क्या होगा? 16 बाइट? हंस पासेंट की टिप्पणी, हालांकि तकनीकी रूप से सत्यापित या परीक्षण नहीं किया जा सकता है, कम से कम सही दिशा में एक संकेत देता है। –

+0

बेशक, यह जानना उपयोगी है कि 64 बिट के लिए चिंता करने की आवश्यकता नहीं है :)। (हालांकि हमारा कोड इस प्रकार के कार्यों को लाखों बार 100 बार सामान्य रूप से कॉल करेगा और सामान्य रूप से घंटों तक चलता है। उस स्थिति में, "सर्वोत्तम" प्रथाओं का पालन करना हमेशा अच्छा होता है। –

1

एक छोटे से सामान्य ज्ञान,

  1. अगर वस्तु एक जटिल प्रतिलिपि निर्माता की आवश्यकता है, यह शायद संदर्भ द्वारा पारित करने के लायक है का उपयोग करें (कि कह - काफी बढ़ावा के वस्तुओं का एक बहुत कुछ करने के लिए डिज़ाइन कर रहे हैं पारित कर दिया-दर- संदर्भ के बजाय मूल्य केवल इसलिए कि आंतरिक कार्यान्वयन काफी छोटा है) एक अजीब एक है जिसे मैंने वास्तव में काम नहीं किया है, std::string, मैं हमेशा इसे संदर्भ से पास करता हूं ...

  2. यदि आप उस मान को संशोधित करना चाहते हैं पारित किया गया है, संदर्भ

  3. 012 का उपयोग करें
  4. अन्यथा, पास-दर-VALUE!

क्या आपके पास कार्यों के तर्कों के साथ एक विशेष प्रदर्शन बाधा है? वरना, अनुकरणीय की तरह है में कैसे एक int पारित हो जाता है के बारे में चिंता ** समुद्र में ing द्वारा बहुत अधिक समय खर्च नहीं करते के बारे में जो सबसे अच्छा तरीका है पारित करने के लिए है चिंता ...

अनुकूलन ...

+0

मैं पहेली को हल करना चाहता हूं: " समुद्र में पिंपिंग " – weberc2

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