C # जैसी प्रबंधित भाषा के साथ गेम लिखते समय क्या विशिष्ट नुकसान होते हैं? [बन्द है]


66

सी # जैसी प्रबंधित भाषा के साथ पीसी के लिए गेम लिखते समय आपको क्या नुकसान हुआ और आपने उन्हें कैसे हल किया?


यह सवाल स्टैक ओवरफ्लो पर बेहतर पूछा गया है, क्योंकि इसके बारे में बहुत कम है जो खेलों के लिए विशिष्ट है।
क्रिस गैरेट

31
@ क्रिस: दृढ़ता से असहमत: सवाल विशेष रूप से खेल का उल्लेख करता है! जब आप हर 16ms को अपडेट करने के लिए उठते हैं तो आपके सामने आने वाली समस्याएं बहुत भिन्न होती हैं जो आपको अधिकांश डेस्कटॉप अनुप्रयोगों में मिलती हैं।
एंड्रयू रसेल

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

@paulecoyote: मैंने केवल C # के बारे में पूछने के लिए प्रश्न को बदल दिया। इसके अलावा, जैसा कि कोई विशिष्ट मंच नहीं है, यह पीसी के बारे में है।
माइकल क्लेमेंट

@ मीकल प्लेटफ़ॉर्मिंग एक खतरनाक धारणा है क्योंकि वे कार्यान्वयन में बहुत भिन्न होते हैं, विशेष रूप से विंडोज का उल्लेख करना और "जैसे" और "जावा" को पूरी तरह से छोड़ना अच्छा होगा।
जूल

जवाबों:


69

मैं जावा के बारे में ज्यादा नहीं जानता, इसलिए यह एक शुद्ध देवता के दृष्टिकोण से है।

अब तक का सबसे बड़ा कचरा है। खिड़कियों पर .net कचरा संग्रहकर्ता एक शानदार काम करता है, और आप इसे सबसे अधिक भाग के बिना बैठे बच्चे से दूर कर सकते हैं। Xbox / winPhone7 पर यह एक अलग मामला है। यदि आपको हर कुछ फ्रेम में स्टॉल मिलते हैं, तो कचरा संग्रह आपको समस्याएं पैदा कर सकता है। फिलहाल यह हर 1mb आवंटन के बाद ट्रिगर होता है।

कचरा से निपटने के लिए कुछ सुझाव। आपको वास्तविकता में इनमें से अधिकांश के बारे में चिंता नहीं करनी चाहिए, लेकिन वे एक दिन काम में आ सकते हैं।

  • GC.GetTotalMemory()स्क्रीन की सामग्री को ड्रा करें । यह आपको आवंटित बाइट्स की मात्रा का एक अनुमान देता है जो आपके खेल का उपयोग करता है। यदि यह मुश्किल से चलता है, तो आप ठीक कर रहे हैं। यदि यह तेजी से बढ़ रहा है, तो आपके पास मुद्दे हैं।
  • सामने अपने सभी ढेर वस्तुओं को आवंटित करने का प्रयास करें । यदि आप खेल शुरू होने से पहले सब कुछ आवंटित नहीं करते हैं, तो हर बार जब आप आवंटन का एक मेगा हिट करते हैं, तो आपका स्टाल जा सकता है। कोई आवंटन नहीं, कोई संग्रह नहीं। इतना सरल है।
  • लोड करने के बाद, GC.Collect () को कॉल करें। यदि आपको पता है कि आपके अधिकांश बड़े आवंटन रास्ते से बाहर हो गए हैं, तो सिस्टम को बताना ही अच्छा रहेगा।
  • GC.Collect()हर फ्रेम को कॉल न करें । यह एक अच्छा विचार की तरह लग सकता है, अपने कचरे के ऊपर और उस सब पर, लेकिन कचरे के संग्रह से भी बदतर के साथ एकमात्र याद रखें कि कचरा संग्रह खत्म हो गया है।
  • देखो तुम्हारा कचरा कहां से आ रहा है। उपयोग करने के बजाय तार को समतल करने जैसे कुछ सामान्य कारण हैं StringBuilder(खबरदार, StringBuilderएक जादू की गोली नहीं है, और अभी भी आवंटन हो सकता है! इसका मतलब है कि एक स्ट्रिंग के अंत में एक नंबर जोड़ने की तरह सरल संचालन, आश्चर्यजनक मात्रा में कचरा पैदा कर सकता है) या इंटरफ़ेस का foreachउपयोग करने वाले संग्रह पर लूप का उपयोग करना, IEnumerableआप को जानने के बिना भी कचरा पैदा कर सकते हैं (उदाहरण के लिए, foreach (EffectPass pass in effect.CurrentTechnique.Passes)एक आम है)
  • सीएलआर मेमोरी प्रोफाइलर जैसे उपकरणों का उपयोग यह पता लगाने के लिए करें कि मेमोरी कहाँ आवंटित की जा रही है। इस उपकरण का उपयोग करने के तरीके के बारे में ट्यूटोरियल के भार हैं।
  • जब आप जानते हैं कि गेमप्ले के दौरान आपका आवंटन कहां है, तो देखें कि क्या आप उस आवंटन की संख्या को कम करने के लिए पूलिंग ऑब्जेक्ट जैसी ट्रिक का उपयोग कर सकते हैं।
  • यदि बाकी सभी विफल हो जाते हैं, तो अपने संग्रह तेजी से चलाएं! कॉम्पैक्ट फ्रेमवर्क पर जीसी आपके कोड के हर संदर्भ का अनुसरण करता है ताकि यह पता लगाया जा सके कि ऑब्जेक्ट अब उपयोग में नहीं हैं। आपके कोड का संदर्भ कम संदर्भ का उपयोग करें!
  • IDisposableउन कक्षाओं पर उपयोग करना याद रखें जिनमें अप्रबंधित संसाधन हैं। आप मेमोरी को साफ करने के लिए इनका उपयोग कर सकते हैं, जीसी स्वयं को मुक्त नहीं कर सकता है।

दूसरी बात यह है कि फ्लोटिंग पॉइंट परफॉर्मेंस। जबकि .Net JITer प्रोसेसर-विशिष्ट ऑप्टिमाइज़ेशन की एक उचित मात्रा में करता है, यह आपके फ़्लोटिंग पॉइंट मैथ्स को गति देने के लिए SSE या किसी अन्य SIMD निर्देश सेट का उपयोग नहीं कर सकता है। यह गेम के लिए C ++ और C # के बीच काफी बड़ा अंतर पैदा कर सकता है। यदि आपके मोनो का उपयोग कर रहे हैं, तो उनके पास कुछ विशेष SIMD गणित पुस्तकालय हैं जिनका आप लाभ उठा सकते हैं।


पूरी तरह से सहमत हैं। "कम" प्लेटफार्मों पर कचरा कलेक्टर कार्यान्वयन पूर्ण कचरा प्रतीत होता है।
क्रिश

अच्छी पोस्ट, हालाँकि आपके बयान के बारे में "सामने की ओर ढेर वस्तुओं का आवंटन" के बारे में, मैं मूल्य प्रकारों के बारे में सच्चाई
जस्टिन

वहाँ महान बिंदु, जब आप कोड को अनुकूलित करते हैं तो वास्तव में उस प्लेटफ़ॉर्म को समझने के लिए जो आपके अनुकूलन की कोशिश कर रहा है। यह वास्तव में मूल्य प्रकार / संदर्भ प्रकारों के बारे में एक टिप्पणी नहीं थी, किसी भी लंबे समय तक रहने वाली वस्तु स्टैक पर होने की संभावना नहीं है। यह वास्तव में सुनिश्चित करता है कि आपके द्वारा किए जा रहे आपके आवंटन में से अधिकांश लोड समय पर किए गए हैं जो आपको खेल खेलने के दौरान उस जादुई 1mb बाधा से नहीं टकराते हैं। सभी .net क्रियान्वयन जो कि xna को लक्षित करते हैं, की एक साफ-सुथरी गारंटी है, समय में एक साथ आवंटित वस्तुओं को अंतरिक्ष में बंद किया जाएगा, जो पूर्ण के लिए अच्छा हो सकता है।
Cubed2D

ऐसा भी लगता है कि मैं यह उल्लेख करना भूल गया कि Xbox पर वर्तमान कॉम्पैक्ट फ्रेमवर्क इनलाइनिंग विधि कॉल से एलर्जी है। अपने सबसे खराब स्थिति वाले परिदृश्‍यों के लिए इसे रखें, हालांकि गणित के रीफ वर्जन का उपयोग करना उतना ही बदसूरत लगता है!
Cubed2D

10

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

C # के लिए, मान ऑब्जेक्ट का उपयोग करना और "स्टेटमेंट" का उपयोग करना GC से दबाव को कम कर सकता है।


3
इसके अतिरिक्त, आप कचरा कलेक्टर को स्पष्ट रूप से चलाने के लिए कह सकते हैं यदि आपने एक आवंटित / मुक्त भारी लूप समाप्त किया है या यदि आपको लगता है कि आपके पास अतिरिक्त चक्र हैं।
बैरेट जे।

16
usingबयान कचरा संग्रहण के साथ कोई संबंध नहीं है! यह उन IDisposableवस्तुओं के लिए है - जो अप्रबंधित संसाधनों को जारी करने के लिए हैं (अर्थात: जिन्हें कचरा कलेक्टर द्वारा संभाला नहीं जाता है )।
एंड्रयू रसेल

9

मैं कहूंगा कि सी # में गेम लिखने में मुझे सबसे बड़ी समस्या सभ्य पुस्तकालयों की कमी की है। मैंने पाया है कि या तो सीधे पोर्ट हैं, लेकिन अपूर्ण हैं, या सी ++ लाइब्रेरी के ऊपर रैपर हैं जो मार्शलिंग के लिए भारी प्रदर्शन का जुर्माना लगाते हैं। (मैं OGRE लाइब्रेरी के लिए विशेष रूप से MOgre और Axiom के बारे में बोल रहा हूं, और Bullet भौतिकी लाइब्रेरी के लिए BulletSharp)

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


सी # और जावा के बारे में यह एक अच्छी बात है कि व्याख्या के बजाय प्रबंधित किया जा रहा है ... मेरे प्रश्न को और अधिक सटीक बनाने के लिए संपादित किया :)
माइकल क्लेमेंट

2
सामान्य रूप से मार्शल करना एक प्रदर्शन अड़चन है, लेकिन यह भी उल्लेखनीय प्रकारों के बारे में जागरूक होने में मदद करता है - ऐसे प्रकार जिन्हें महत्वपूर्ण प्रदर्शन प्रभाव के बिना अप्रबंधित मेमोरी में सीधे मैप किया जा सकता है। msdn.microsoft.com/en-us/library/75dwhxf7.aspx
सीन एडवर्ड्स

8

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


4

C # और Java की व्याख्या नहीं की गई है। वे एक मध्यवर्ती बायोटेक पर संकलित किए जाते हैं, जो JIT के बाद , मूल कोड के समान तेज़ हो जाता है (या पास पर्याप्त नहीं होता है)

मैंने पाया सबसे बड़ा नुकसान उन संसाधनों को मुक्त करना है जो सीधे उपयोगकर्ता के अनुभव को प्रभावित करते हैं। ये भाषाएँ स्वचालित रूप से नियतात्मक अंतिमकरण का समर्थन नहीं करती हैं जैसे कि C ++ करता है, यदि आप उम्मीद नहीं कर रहे हैं कि इससे आपको लगता है कि वे नष्ट हो जाने के बाद दृश्य के बारे में फ़्लोटिंग जैसी चीज़ों को जन्म दे सकते हैं। (C # IDis प्रयोज्य के माध्यम से निर्धारक अंतिम रूप देता है , मुझे यकीन नहीं है कि जावा क्या करता है।)

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


हाँ, नोट के लिए धन्यवाद, पहले से ही व्याख्या की गई / प्रबंधित चीज़ को ठीक किया;) इसके अलावा, दृश्य के बारे में तैरते हुए मेश के साथ अच्छा बिंदु। यह नहीं सोचा था कि जब जीसी समस्याओं के बारे में सोचते हैं ...
माइकल क्लेमेंट

1
IDisposableसमय-महत्वपूर्ण और अप्रबंधित संसाधनों के निर्धारक सफाई की अनुमति देता है, लेकिन अंतिम रूप देने या कचरा संग्रहकर्ता को सीधे प्रभावित नहीं करता है।
सैम हरवेल

4

न तो जावा और न ही C # की व्याख्या की जाती है। दोनों को देशी मशीन कोड में संकलित किया जाता है।

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


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

4
यह ध्यान देने योग्य है कि .NET 4 में, कचरा संग्रहकर्ता ऑब्जेक्ट की सभी तीन पीढ़ियों के लिए पृष्ठभूमि संग्रह का समर्थन करता है। इससे खेलों में कचरा संग्रहण के प्रदर्शन प्रभाव को प्रभावी ढंग से कम किया जाना चाहिए। प्रासंगिक लिंक: geekswithblogs.net/sdorman/archive/2008/11/07/…
माइक स्ट्रोबेल

कचरा संग्रहकर्ता विकसित हो रहे हैं, और जैसा कि माइक स्ट्रोबेल ने कहा है, कुछ पहले से ही उत्पादन में हैं जो लगभग इस नुकसान को खत्म करते हैं।
सैम हरवेल

2
देशी मशीन कोड को न तो C # और न ही जावा संकलित किया जाता है। C # MSIL और Java को bytecode के लिए संकलित करता है। कचरा संग्रह कोई "लंबी" रोक नहीं देगा, लेकिन यह "हिचकी" दे सकता है।
क्लाउड जूल

2

एक बड़ी गड़बड़ी मैं इन जैसी भाषाओं के साथ खेल बनाने से देखता हूं (या XNA, टॉर्कएक्स इंजन इत्यादि जैसे उपकरणों का उपयोग करके) यह है कि आपको एक समान खेल बनाने के लिए आवश्यक विशेषज्ञता वाले अच्छे लोगों की टीम ढूंढने के लिए कड़ी मेहनत करनी होगी C ++ और OpenGL / DirectX में लोगों को ढूंढना काफी आसान होगा।

खेल देव उद्योग अभी भी C ++ में बहुत अधिक भारी है, क्योंकि अधिकांश उपकरण और पाइपलाइन का उपयोग बड़े या बस पॉलिश किए गए छोटे खेलों को C ++ में करने के लिए किया जाता है, और जहाँ तक मुझे पता है आप सभी आधिकारिक देव किट के बारे में जान सकते हैं। XBox, PS3, और Wii के लिए केवल C ++ के लिए संगतता के साथ जारी किया जाता है (XBox टूलसेट को आजकल अधिक प्रबंधित किया जा सकता है, किसी को अधिक पता है?)

यदि आप अभी कंसोल के लिए गेम विकसित करना चाहते हैं, तो आपको एक्सएनएक्सएक्स पर XNA और C # बहुत मिलता है और उसके बाद गेम लाइब्रेरी के केवल एक हिस्से में XBox लाइव इंडी गेम्स कहा जाता है। प्रतियोगिता जीतने वाले कुछ लोग अपने गेम को वास्तविक एक्सबॉक्स लाइव आर्केड में पोर्ट करने के लिए चुने जाते हैं। पीसी के लिए एक गेम बनाने पर उस योजना के अलावा अन्य।

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