2009-03-11 11 views
8

64 बिट जेआईटी बनाम 32 बिट जेआईटी के तहत अपने .NET अनुप्रयोगों को चलाने से स्विच करते समय प्रदर्शन, स्मृति इत्यादि के मामले में असामान्य, अप्रत्याशित परिणाम हुए हैं? मुझे अच्छे में दिलचस्पी है, लेकिन लोगों ने आश्चर्यजनक रूप से खराब मुद्दों में दिलचस्पी है।मेरा 32 बिट सिरदर्द अब 64 बिट माइग्रेन है?! (या 64 बिट .NET CLR रनटाइम समस्याएं)

मैं एक नया .NET एप्लिकेशन लिखने की प्रक्रिया में हूं जो 32 बिट और 64 बिट दोनों में तैनात किया जाएगा। एप्लिकेशन को पोर्ट करने के मुद्दों से संबंधित कई प्रश्न हैं - मैं "gotchas" from a programming/porting standpoint से अनजान हूं। (यानी: देशी/COM इंटरऑप को सही ढंग से संभालने, संरचनाओं के आकार को बदलने वाले structs में एम्बेडेड संदर्भ प्रकार)

हालांकि, this question and it's answer मुझे सोच रहा है - मैं अन्य मुद्दों को किस प्रकार देख रहा हूं?

ऐसे कई प्रश्न और ब्लॉग पोस्ट हैं जो इस मुद्दे के आसपास स्कर्ट करते हैं, या इसके एक पहलू को दबाते हैं, लेकिन मैंने कुछ भी नहीं देखा है जो समस्याओं की एक सभ्य सूची संकलित है।

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

  • (Now I know that) गुण, यहां तक ​​कि स्वत: गुण, 64 में inlined नहीं मिलता:

    यहाँ कुछ मुद्दों मैं वर्तमान के बारे में पता कर रहा हूँ कर रहे हैं।

  • आवेदन परिवर्तन की स्मृति प्रोफ़ाइल, size of references की वजह से दोनों, लेकिन यह भी स्मृति allocator अलग प्रदर्शन विशेषताओं
  • है क्योंकि
  • Startup times can suffer on x64

मुझे पता है कि अन्य क्या, विशिष्ट, लोगों को जारी करता है करना चाहते हैं 64 बिट विंडोज़ पर जेआईटी में खोजा है, और यदि प्रदर्शन के लिए कोई कामकाज भी है।

सभी को धन्यवाद!

---- संपादित करें -----

बस स्पष्ट करने के लिए -

मुझे पता है कि जल्दी अनुकूलित करने की कोशिश अक्सर खराब है हूँ। मुझे पता है कि सिस्टम का दूसरा अनुमान अक्सर खराब होता है। मुझे यह भी पता है कि 64 बिट के पोर्टेबिलिटी के अपने मुद्दे हैं - हम रोज़ाना 64 बिट सिस्टम पर चलने और परीक्षण करने के लिए परीक्षण करते हैं। आदि

मेरा आवेदन, हालांकि, आपका सामान्य व्यावसायिक अनुप्रयोग नहीं है। यह एक वैज्ञानिक सॉफ्टवेयर एप्लीकेशन है। हमारे पास कई प्रक्रियाएं हैं जो एक समय में सभी कोरों (यह अत्यधिक थ्रेडेड) पर 100% सीपीयू का उपयोग कर बैठती हैं।

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

+0

यदि यह शीर्षक .NET 32- और 64-बिट रनटाइम को संदर्भित किया गया है तो यह धागा बहुत उपयोगी होगा (Google या Stacko-Search, आदि के साथ ढूंढना आसान है)। –

उत्तर

3

मुझे अक्सर आईआरसी चैनल से एक समस्या सुनना याद है।

EventHandler temp = SomeEvent; 
if(temp != null) 
{ 
    temp(this, EventArgs.Empty); 
} 

रेस स्थिति में वापस लाना और संभावित रिक्त संदर्भ अपवाद के कारण: यह इस उदाहरण में अस्थायी प्रतिलिपि दूर अनुकूलित करता है।

+0

दिलचस्प .... क्या एक अनुकूलन है जो केवल 64 बिट जेआईटी पर होता है, या यह 32 बिट जेआईटी पर भी होता है? –

+0

32 बिट में नहीं होता है।यह मेरी वार्तालाप नहीं थी इसलिए मेरे पास इसका सत्यापन करने का कोई तरीका नहीं है, लेकिन वार्तालाप एक अच्छे घंटे के लिए चला गया, इसलिए जब तक इसके आसपास कुछ अन्य 64 बिट जिटर न हो तो आप – Quibblesome

+0

आईआईआरसी पर काम कर रहे हैं 32 बिट जिटर वास्तव में इस उदाहरण में spec के अनुरूप नहीं है और इसे वैसे भी इस फैशन में अनुकूलित किया जाना चाहिए। लेकिन यह एक चाल है जो घटनाओं को फायर करते समय दौड़ की स्थिति को रोकने और विभिन्न धागे के माध्यम से dehooking – Quibblesome

-1

मुझे लगता है कि 64-बिट मुद्दों से परिचित नहीं हूँ, लेकिन मैं एक टिप्पणी है:

हम, छोटे क्षमता के बारे में भूल जाना चाहिए कहते हैं कि समय की 97%: समय से पहले अनुकूलन है सभी बुराई की जड़। - डोनाल्ड Knuth

+4

लेकिन हमेशा ऐसा होता है कि 3% शापित ... –

+0

जैसा कि मैंने कहा, मेरा आवेदन बेहद सीपीयू बाध्य है। मेरे पास 5 घंटे रनटाइम के साथ प्रक्रिया है। आपकी टिप्पणी का फ्लिपसाइड यह है कि समय का 3%, यह सभी बुराई की जड़ नहीं है। इस पर रिको मारियानी की टिप्पणी लें- यदि यह केवल 3% समय मायने रखती है, तो इसका मतलब है कि अनुकूलन के लिए 33 मामलों में कोड में से एक पंक्ति है। –

+0

जिज्ञासा से, क्या इन समस्याओं को अभी भी प्रदर्शित किया गया है यदि आप किसी भी सीपीयू के बजाय वीएस में 64-बिट प्लेटफार्मों को लक्षित करते हैं? – Powerlord

1

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

+0

हाँ - हालांकि, मैं इन प्रकार के मुद्दों से बहुत चिंतित नहीं हूं। मैं प्रदर्शन/स्मृति/रनटाइम मुद्दों से अधिक चिंतित हूं जो छिपे हुए गठिया हैं। –

+0

+1 - मैंने इस मुद्दे में मेरी थर्ड पार्टी लाइब्रेरीज़ में से एक के साथ भाग लिया है। मुझे अपने इंस्टॉलर में 32 और 64 बिट संस्करण दोनों शामिल करना होगा और उचित संस्करण स्थापित करना होगा। –

1

आपने पोर्टिंग मुद्दों का उल्लेख किया है, वे जिनके साथ चिंतित हैं। मैं (जाहिर है) अपने आवेदन को नहीं जानता, लेकिन दूसरे अनुमान लगाने की कोशिश कर रहा है कि जेआईटी अक्सर समय की पूरी बर्बादी है। जेआईटी लिखने वाले लोगों में x86/x64 चिप आर्किटेक्चर की गहरी समझ है, और सभी संभावनाओं में पता है कि क्या बेहतर प्रदर्शन करता है और ग्रह पर शायद किसी और से भी बदतर प्रदर्शन करता है।

हां, यह संभव है कि आपके पास एक कोने केस है जो अलग और अद्वितीय है, लेकिन यदि आप "नया एप्लिकेशन लिखने की प्रक्रिया में हैं" तो मैं जेआईटी कंपाइलर के बारे में चिंता नहीं करता। संभवतः एक मूर्खतापूर्ण पाश है जिसे कहीं से बचा जा सकता है जो आपको 100x प्रदर्शन सुधार में खरीद देगा जो आपको जेआईटी का अनुमान लगाने की कोशिश करने से मिलेगा। मुझे हमारे ओआरएम लिखने में लगे मुद्दों के बारे में याद दिलाता है, हम कोड देखेंगे और सोचेंगे कि हम इसके बारे में कुछ मशीन निर्देशों को ट्वीक कर सकते हैं ... बेशक, कोड तब चला गया और नेटवर्क पर डेटाबेस सर्वर से कनेक्ट हो गया , इसलिए हम एक प्रक्रिया से माइक्रोसेकंड को ट्रिम कर रहे थे जो कहीं और मिलीसेकंड से घिरा हुआ था।

प्रदर्शन फेरबदल की सार्वभौम नियम ... कि आप अपने प्रदर्शन आप पता नहीं है जहाँ आपके बाधाओं हैं मापा नहीं किया है, तो आप सिर्फ लगता तुम्हें पता है ... और आप की संभावना गलत हैं।

+0

वाल्डन: मैं सहमत हूं। मेरा ऐप, हालांकि, बहुत सीपीयू बाउंड है। यह अत्यधिक गणितीय है, और इसमें कई बहु-घंटे रनटाइम प्रक्रियाएं हैं। मैं बहुत समय बिताता हूं और बढ़िया विवरण अनुकूलित करता हूं, जो नाटकीय रूप से सहायक हो सकता है। हालांकि, प्रोफेसर मुश्किल हैं, क्योंकि वे जेआईटी मुद्दों को अक्षम करते हैं। –

1

Quibblesome के जवाब के बारे में:

मैं डिबगर के बिना मेरे रिलीज मोड में विंडोज 7 64 में निम्न कोड भागने की कोशिश की, और NullReferenceException फेंक दिया नहीं किया गया है।

using System; 
using System.Threading; 

namespace EventsMultithreadingTest 
{ 
    public class Program 
    { 
     private static Action<object> _delegate = new Action<object>(Program_Event); 
     public static event Action<object> Event; 

     public static void Main(string[] args) 
     { 
      Thread thread = new Thread(delegate() 
       { 
        while (true) 
        { 
         Action<object> ev = Event; 

         if (ev != null) 
         { 
          ev.Invoke(null); 
         } 
        } 
       }); 
      thread.Start(); 

      while (true) 
      { 
       Event += _delegate; 
       Event -= _delegate; 
      } 
     } 

     static void Program_Event(object obj) 
     { 
      object.Equals(null, null); 
     } 
    } 
} 
+2

यह समस्या केवल x64 पर .NET 1.x में मौजूद थी; यह कोई मुद्दा नहीं रहा है क्योंकि 2005 में .NET 2.0 मेमोरी मॉडल पेश किया गया था; http://code.logos.com/blog/2008/11/events_and_threads_part_4.html और http://msdn.microsoft.com/magazine/cc163715.aspx देखें –

0

मैं 64 JIT पूरी तरह से इस तरह के 64 बिट वास्तुकला सीपीयू का लाभ लेने के तो यह समस्या नहीं है पोर्टेड विकसित नहीं है/विश्वास करते हैं, तो आप अपने विधानसभाओं के 'अनुकरणीय' व्यवहार जो मुद्दों और अप्रत्याशित कारण हो सकता है मिल रहे हों, व्यवहार। मैं उन मामलों में देखता हूं जहां इसे टाला जा सकता है और/या शायद यह देख सकता है कि समय के लिए महत्वपूर्ण कंप्यूटेशंस और एल्गोरिदम लिखने के लिए 64 सी ++ कंपाइलर अच्छा है या नहीं।लेकिन यहां तक ​​कि अगर आपको जानकारी खोजने में कठिनाई हो रही है या विघटित कोड के माध्यम से पढ़ने का कोई समय नहीं है, तो मुझे पूरा यकीन है कि प्रबंधित कोड के बाहर भारी गणना करने से आपके पास & प्रदर्शन को बढ़ावा मिलेगा [कुछ हद तक यकीन है कि आप इसे पहले से ही कर रहे हैं लेकिन बस उल्लेख करने के लिए :)]

0

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

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

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

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

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

आप कहते हैं कि "स्टार्टअप समय लंबा हो सकता है", लेकिन ऐसा लगता है कि आप घंटे के लिए 100% CPU पर चलने वाले एप्लिकेशन में अप्रासंगिक लगते हैं।

तो आप वास्तव में किस बारे में चिंतित हैं? हो सकता है कि 32-बिट पीसी पर आपका कोड हो और फिर यह 64-बिट पीसी पर एक ही कार्य कर रहा हो। क्या 4 घंटे के रन पर आधे घंटे का अंतर है? या अंतर केवल 3 सेकंड है? या 64 बिट पीसी वास्तव में तेज है? शायद आप उन समस्याओं के समाधान की तलाश में हैं जो अस्तित्व में नहीं हैं।

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

4

एक विशेष रूप से परेशानी प्रदर्शन समस्या में।

https://connect.microsoft.com/VisualStudio/feedback/details/93858/struct-methods-should-be-inlined?wa=wsignin1.0

असल में, इनलाइन करने और structs 64 पर अच्छी तरह से एक साथ काम नहीं करते हैं (हालांकि उस पृष्ठ अब इनलाइनिंग पता चलता है लेकिन बाद में redunant प्रतियां समाप्त नहीं कर रहे हैं काम करता है, कि लगता है: नेट गरीब JIT से संबंधित है संदिग्ध छोटे perf अंतर दिया)।

किसी भी मामले में, इसके लिए लंबे समय तक .NET के साथ कुश्ती के बाद, मेरा समाधान कुछ भी संख्यात्मक रूप से गहन के लिए सी ++ का उपयोग करना है। यहां तक ​​कि .NET के लिए "अच्छे" मामलों में, जहां आप structs से निपट नहीं रहे हैं और उन सरणी का उपयोग कर रहे हैं जहां सीमा-जांच को ऑप्टिमाइज़ किया गया है, सी ++ धड़कता है .NET hands down

यदि आप डॉट उत्पादों की तुलना में कुछ अधिक जटिल कर रहे हैं, तो तस्वीर बहुत जल्दी हो जाती है; .NET कोड दोनों + कम पठनीय है (क्योंकि आपको मैन्युअल रूप से इनलाइन सामग्री और/या जेनेरिक का उपयोग नहीं करनी चाहिए), और बहुत धीमी है।

मैंने सी ++ में Eigen का उपयोग करने के लिए स्विच किया है: यह बिल्कुल बढ़िया है, जिसके परिणामस्वरूप पठनीय कोड और उच्च प्रदर्शन होता है; एक पतली सी ++/सीएलआई रैपर तब गणना इंजन और .NET दुनिया के बीच गोंद प्रदान करता है।

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

तो, उदाहरण के लिए, यदि P एक मैट्रिक्स है, सामान के इस प्रकार बस काम करता है:

1.0/(P.transpose() * P).diagonal().sum(); 

... जो पी के एक अस्थायी रूप से स्थानांतरित संस्करण का आवंटन नहीं है, और गणना नहीं करता है पूरे मैट्रिक्स उत्पाद लेकिन केवल फ़ील्ड की जरूरत है।

तो, यदि आप पूर्ण ट्रस्ट में भाग सकते हैं - तो सी ++/सीएलआई के माध्यम से सी ++ का उपयोग करें, यह बहुत बेहतर काम करता है।

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