2012-02-22 9 views
5

मुझे आकार में 8 बाइट तक की संरचनाओं की बात आती है, लेकिन बड़े पीओडी प्रकारों के बारे में क्या कोई फर्क नहीं पड़ता है? क्या मूल्य के आधार पर गुजरता है जब आकार का आकार मशीन शब्द आकार से अधिक हो जाता है या क्या कुछ और है (कैश लाइन आकार की तरह) जो प्रदर्शन को प्रभावित कर सकता है?x64 पर मान के आधार पर आकार (myPOD) बहुत बड़ा कब होता है?

मैं मुख्य रूप से x64 में रूचि रखता हूं, लेकिन x86 के लिए कुछ संख्याओं को भी शामिल करने में संकोच न करें।

स्पष्टीकरण:

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

कुछ बिंदु पर, 8 बाइट से पहले, संकलक स्थानीय प्रतिलिपि बनाने के लिए कोड उत्पन्न करता है और उस प्रतिलिपि को एक पॉइंटर पास करता है। बस इसे आज़माएं, जेनरेट किए गए मशीन कोड को देखें। –

उत्तर

7

आप दो अलग-अलग मुद्दों को भ्रमित कर रहे हैं। आप मूल्य से किसी भी ऑब्जेक्ट को पास कर सकते हैं (जब तक यह कॉपी करने योग्य हो)।

एक रजिस्टर में या स्टैक पर पारित किया जाएगा या नहीं, कार्यान्वयन और विशेष रूप से, कॉलिंग सम्मेलन का उपयोग किया जाता है।

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

कुछ के तहत, यह संभव है कि ऑब्जेक्ट्स कभी भी रजिस्टरों में उनके आकार के बावजूद पास हो जाएं।

इसी तरह, कुछ कॉलिंग सम्मेलनों में रजिस्टरों में सिम मूल्य (एसएसई/एवीएक्स) पारित किया जा सकता है, लेकिन हमेशा दूसरों में ढेर पर रखा जाएगा। और स्केलर फ़्लोटिंग-पॉइंट मानों के लिए भी यह सच हो सकता है।

लेकिन आप जो पूछ रहे हैं वह वास्तव में अर्थपूर्ण उत्तर नहीं दिया जा सकता है। किसी ऑब्जेक्ट को कॉपी करने की गति ऑब्जेक्ट के आकार से प्रभावित होती है, हां।यदि ऑब्जेक्ट एक पीओडी प्रकार है, और यह एक रजिस्टर में फिट बैठता है, तो यह को सरल mov निर्देश के साथ कॉपी किया जा सकता है। कंपाइलर करेगा जो कंपाइलर पर है या नहीं।

और जाहिर है, वस्तु जितनी बड़ी होगी, उतनी अधिक कैश स्पेस लेती है, जिसका अर्थ है कि आपको अधिक कैश मिस मिलेंगे।

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

अपने संपादित के जवाब में

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

पहले, अपने संकलक पर भरोसा है। यह आक्रामक तरीके से दूर प्रतियां अनुकूलित करेंगे कई स्थितियों में, तो भले ही आप मूल्य से एक बड़ी वस्तु पारित कर , यह एक मापनीय समस्या होने की संभावना नहीं है।

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

लेकिन 8, 16, 24, 40 बाइट्स की वस्तुओं के लिए? कौन जानता है? किसे पड़ी है? वास्तविक कोड में मापने योग्य अंतर बनाने की संभावना नहीं है।

कौन सा मुझे अंगूठे का दो नियमों की ओर जाता है:

  1. करना क्या प्राकृतिक लगता है: यदि प्रतिलिपि से गुज़र अपने कोड सरल या स्वच्छ बनाता है, कि है।
  2. यदि प्रदर्शन महत्वपूर्ण है, तो (1) सुनिश्चित करें कि वास्तव में आप जो देख रहे हैं वह है आपके प्रदर्शन पर ध्यान देने योग्य प्रभाव। इसे मापो। यदि यह प्रदर्शन को प्रभावित करता है, तो इसे मापा जा सकता है। यदि इसे मापा नहीं जा सकता है, तो प्रदर्शन में अंतर, परिभाषा के अनुसार, ध्यान देने योग्य नहीं हो सकता है।

तो, संक्षेप में:

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

मुझे पता है कि किसी भी वस्तु को मूल्य से पारित किया जा सकता है, मैं बस कुछ कठिन संख्या चाहता था बशर्ते कि मुझे सभी विवरण पता हों। ऐसा लगता है कि मैं खेल में आने वाली हर चीज को नहीं जानता। मेरी स्पष्टीकरण देखें। –

+0

यदि आप कठिन संख्या चाहते हैं, तो इसे मापें। :) संयोग से, यदि आप प्रदर्शन के बारे में चिंतित हैं तो यह भी एकमात्र नियम है: यदि आपको यह जानने की आवश्यकता है कि कौन सा तेज़ है, तो इसे मापें। यदि आप अंतर को माप नहीं सकते हैं, इससे कोई फर्क नहीं पड़ता। – jalf

+2

मुझे लगता है कि मैं जो खोज रहा था वह x64 कॉलिंग सम्मेलन के लिए प्रलेखन था। http://msdn.microsoft.com/en-us/library/ms235286(v=vs.100).aspx यह अच्छी तरह से बताता है: "कोई भी तर्क जो 8 बाइट्स में फिट नहीं है, या 1, 2, 4 नहीं है , या 8 बाइट्स, संदर्भ द्वारा पारित किया जाना चाहिए। एकाधिक रजिस्टरों में एक भी तर्क फैलाने का कोई प्रयास नहीं है। " –

0

आपको दो चीजों से संबंधित होना चाहिए - डेटा कॉपी और स्टैक उपयोग।

डेटा प्रतिलिपि में समय लगता है। संरचना जितनी बड़ी होगी, इसे कॉपी करने में उतना ही समय लगेगा। चाहे यह एक प्रदर्शन है या नहीं, इस पर निर्भर करता है कि आप कितनी बार ऐसा करते हैं, और आपके कोड की प्रदर्शन आवश्यकताओं क्या हैं।

ढेर बड़ा है, लेकिन अनंत नहीं है। मूल्य से बड़े ढांचे को पास करना, विशेष रूप से यदि रिकर्सन के साथ संयुक्त हो, तो आसानी से इसे बहने का कारण बन सकता है।

x86_64 (WIN64 या Linux सम्मेलनों का उपयोग करके) के साथ, रजिस्टरों में डेटा पास करने का छोटा बिंदु है। यदि पैरामीटर प्रत्येक 8 बाइट तक हैं, तो पहले 6 रजिस्टरों में पास किए जाते हैं, जो तेज़ होते हैं। X86 के साथ, अधिकांश सम्मेलन ऐसा नहीं करते हैं (लिनक्स कर्नेल, हालांकि पैरामीटर के लिए 3 रजिस्टरों का उपयोग करता है)।
रेगस्टर्स का उपयोग कुछ हद तक तेज है। लेकिन 8 बाइट्स और 1000 बाइट्स की प्रतिलिपि बनाने के बीच अंतर की तुलना में स्टैक या रजिस्टर का उपयोग करके 8 बाइट्स पास करने के बीच अंतर छोटा है।

+0

"x86 डिफ़ॉल्ट रूप से ऐसा नहीं करता है"? क्या? x86 डिफ़ॉल्ट रूप से कुछ भी नहीं करता है, इसलिए "ओवरराइड" करने के लिए कुछ भी नहीं है। कॉलिंग सम्मेलन पर निर्णय लेने के लिए यह संकलक पर निर्भर करता है। – jalf

+0

@jalf, हाँ, मैं सटीक नहीं था। सामान्य x86 कॉलिंग सम्मेलन, यानी लिनक्स और विंडोज़, ऐसा मत करो। – ugoren

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