रेंडरिंग, बैच, ग्राफिकल कार्ड, प्रदर्शन आदि के बारे में जानकारी + XNA?


12

मुझे पता है कि शीर्षक थोड़ा अस्पष्ट है, लेकिन यह वर्णन करना कठिन है कि मैं वास्तव में क्या देख रहा हूं, लेकिन यहां जाता है।

जब सीपीयू रेंडरिंग की बात आती है, तो प्रदर्शन ज्यादातर अनुमान लगाने में आसान और सीधा होता है, लेकिन जब तकनीकी पृष्ठभूमि की जानकारी की कमी के कारण यह जीपीयू की बात आती है, तो मैं क्लूलेस हूं। मैं XNA का उपयोग कर रहा हूं, तो यह अच्छा होगा यदि सिद्धांत उस से संबंधित हो सकता है।

तो मैं वास्तव में जानना चाहता हूं कि क्या होता है, जब आप विशिष्ट ड्रॉ क्रिया करते हैं तो कब और कहां (सीपीयू / जीपीयू) होता है? एक बैच क्या है? प्रभाव, अनुमान आदि क्या प्रभाव डालते हैं? क्या ग्राफिक्स कार्ड पर डेटा कायम है या इसे हर कदम पर हस्तांतरित किया जाता है? जब बैंडविड्थ के बारे में बात होती है, तो क्या आप ग्राफिक्स कार्ड आंतरिक बैंडविड्थ, या सीपीयू से जीपीयू के बारे में बात कर रहे हैं?
नोट: मैं वास्तव में जानकारी की तलाश नहीं कर रहा हूं कि ड्राइंग प्रक्रिया कैसे होती है, यह GPU का व्यवसाय है, मैं उस सभी ओवरहेड पर दिलचस्पी रखता हूं जो उससे पहले है।

मैं यह समझना चाहता हूं कि जब मैं एक्शन एक्स कर रहा हूं, तो मेरे आर्किटेक्चर और प्रथाओं को उसके अनुकूल बनाने के लिए।

कोई भी लेख (संभवतः कोड उदाहरण के साथ), जानकारी, लिंक, ट्यूटोरियल जो बेहतर गेम लिखने के तरीके में अधिक अंतर्दृष्टि देते हैं, बहुत सराहना करते हैं। धन्यवाद :)


2
हालांकि यह मूल रूप से XNA था, मैंने डायरेक्टएक्स टैग जोड़ा है, क्योंकि यह अंतर्निहित तकनीक है - इससे आपको बेहतर उत्तर प्राप्त करने में मदद मिल सकती है। इसके अलावा बाहर की जाँच इस जवाब है जो आप एक अच्छा प्रारंभिक बिंदु दे सकता है।
एंड्रयू रसेल

@AndrewRussell बहुत बहुत धन्यवाद :)। मैं वास्तव में पहले से ही इस विषय पर विभिन्न लेखों को पढ़ चुका हूं। लेकिन इसमें वह सब कुछ शामिल नहीं है जो मैं जानना चाहता हूं।
एदियाकापी

जवाबों:


20

मुझे " सीमा " के संदर्भ में प्रदर्शन के बारे में सोचना पसंद है । यह एक काफी जटिल, परस्पर प्रणाली को अवधारणा करने का एक आसान तरीका है। जब आपके पास प्रदर्शन की समस्या होती है, तो आप सवाल पूछते हैं: "मैं किस सीमा तक मार रहा हूं?" (या: "क्या मैं सीपीयू / जीपीयू बाध्य हूं?")

आप इसे कई स्तरों में तोड़ सकते हैं। उच्चतम स्तर पर आपके पास सीपीयू और जीपीयू है। आप सीपीयू बाउंड (जीपीयू सिटिंग आइडल सीपीयू के इंतजार में) हो सकते हैं, या जीपीयू बाउंड (सीपीयू जीपीयू पर इंतजार कर रहे हैं)। यहाँ विषय पर एक अच्छा ब्लॉग पोस्ट है

आप इसे और नीचे तोड़ सकते हैं। पर सीपीयू ओर, आप सीपीयू कैश में पहले से ही डेटा पर अपने सभी चक्रों का उपयोग कर हो सकता है। या हो सकता है कि आप मेमोरी सीमित हों , जिससे मुख्य मेमोरी से डेटा के आने के लिए सीपीयू बेकार हो जाए ( इसलिए अपने डेटा लेआउट को ऑप्टिमाइज़ करें )। आप इसे अभी और भी तोड़ सकते हैं।

(हालांकि मैं एक्सएनए के संबंध में प्रदर्शन का एक विस्तृत अवलोकन कर रहा हूं, मैं इंगित करूंगा कि एक संदर्भ प्रकार का आवंटन ( classनहीं struct), जबकि सामान्य रूप से सस्ता है, कचरा कलेक्टर को ट्रिगर कर सकता है, जो बहुत सारे चक्रों को जला देगा - विशेष रूप से Xbox 360 पर । यहाँ देखें जानकारी के लिए)।

पर GPU ओर, मैं करने के लिए आप इंगित कर बाहर शुरू करेंगे इस उत्कृष्ट ब्लॉग पोस्ट जो विवरण के बहुत सारे है। यदि आप पाइपलाइन पर विस्तार का एक पागल स्तर चाहते हैं , तो ब्लॉग पोस्ट की इस श्रृंखला को पढ़ें । ( यहाँ एक सरल है )।

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

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

लेकिन, मूल रूप से, एक बैच ( जैसा कि आप पहले से ही जानते हैं ) तब भी होता है जब आप किसी एक GraphicsDevice.Draw*फ़ंक्शन (या एक्सएनए का हिस्सा, जैसे SpriteBatch, आपके लिए ऐसा करता है) कहते हैं। जैसा कि आप कोई संदेह पहले से ही पढ़ चुके हैं, आपको प्रति फ्रेम कुछ हजार * मिलते हैं । यह एक सीपीयू सीमा है - इसलिए यह आपके अन्य सीपीयू उपयोग के साथ प्रतिस्पर्धा करता है। यह मूल रूप से ड्रायवर है जो आपने इसे तैयार करने, और इसे GPU पर भेजने के बारे में बताया है।

और फिर GPU के लिए बैंडविड्थ है। यह है कि आप कितना कच्चा डेटा वहां स्थानांतरित कर सकते हैं। इसमें सभी राज्य जानकारी शामिल है जो बैचों के साथ जाती है - DrawUser*कार्यों का उपयोग करते समय लंबवत करने के लिए प्रतिपादन राज्य और shader स्थिरांक / पैरामीटर (जिसमें विश्व / दृश्य / प्रोजेक्ट मैट्रिस जैसी चीजें शामिल हैं) सेट करने से सब कुछ शामिल है । यह भी करने के लिए कोई कॉल भी शामिल SetDataऔर GetDataबनावट, शिखर बफ़र्स, आदि पर

इस बिंदु पर मुझे यह कहना चाहिए कि कुछ भी जिसे आप SetData(बनावट, शीर्ष और सूचकांक बफ़र्स, आदि) पर कॉल कर सकते हैं , साथ ही साथ EffectGPU मेमोरी में रहता है। इसे लगातार GPU में दोबारा नहीं भेजा जाता है। एक ड्रॉ कमांड जो उस डेटा को केवल एक पॉइंटर के साथ भेजा जाता है, उस संदर्भ को संदर्भित करता है।

(इसके अलावा, आप केवल मुख्य थ्रेड से ड्रॉ कमांड भेज सकते हैं, लेकिन आप SetDataकिसी भी धागे पर कर सकते हैं ।)

XNA इसकी प्रस्तुत करना राज्य वर्गों (साथ कुछ हद तक बातें पेचीदा हो BlendState, DepthStencilState, आदि)। यह स्टेट डेटा प्रति ड्रा कॉल (प्रत्येक बैच में) भेजा जाता है । मुझे 100% यकीन नहीं है, लेकिन मैं इस धारणा के तहत हूं कि इसे आलसी (इसे केवल राज्य भेजता है जो बदलता है) भेजा जाता है। किसी भी तरह से, राज्य परिवर्तन एक बैच की लागत के सापेक्ष, मुफ्त के बिंदु पर सस्ते हैं।

अंत में, उल्लेख करने के लिए अंतिम बात आंतरिक GPU पाइपलाइन है । आप डेटा को लिखने के लिए इसे फ्लश करने के लिए मजबूर नहीं करना चाहते हैं कि इसे अभी भी पढ़ना है, या डेटा को पढ़ना है जिसे इसे अभी भी लिखना है। एक पाइपलाइन फ्लश का मतलब है कि यह ऑपरेशन खत्म होने का इंतजार करता है, ताकि डेटा एक्सेस होने पर सब कुछ एक सुसंगत स्थिति में हो।

दो विशेष मामलों को देखने के लिए: GetDataकुछ भी गतिशील पर कॉल करना - विशेष रूप से RenderTarget2Dउस पर जो GPU के लिए लिख रहा हो सकता है। यह प्रदर्शन के लिए बहुत बुरा है - ऐसा न करें।

अन्य मामला SetDataशीर्ष / सूचकांक बफ़र्स पर कॉल कर रहा है । यदि आपको अक्सर ऐसा करने की आवश्यकता होती है, तो DynamicVertexBuffer(भी DynamicIndexBuffer) का उपयोग करें । ये GPU को यह जानने की अनुमति देते हैं कि वे अक्सर बदलते रहेंगे, और पाइपलाइन फ्लश से बचने के लिए आंतरिक रूप से कुछ बफ़रिंग जादू करेंगे।

(यह भी ध्यान दें कि गतिशील बफ़र DrawUser*विधियों की तुलना में तेज़ हैं - लेकिन उन्हें अधिकतम आवश्यक आकार पर पूर्व-आवंटित करना होगा।)

... और वह सब कुछ है जो मुझे XNA प्रदर्शन के बारे में पता है :)


बहुत बहुत धन्यवाद! यह वही है जो मैं देख रहा था और :) की उम्मीद कर रहा था।
ऐड़ीयाकापी

1
फ्रेम प्रति कुछ सौ बैचों निराशावादी लगता है। मैंने हमेशा सुना है कि अंगूठे का नियम 2k से 3K बैच प्रति फ्रेम है। कुछ गेम पीसी पर 10K तक जाने के लिए जाने जाते हैं, लेकिन मुझे लगता है कि इसे हासिल करने के लिए बहुत देखभाल की आवश्यकता होती है।
नाथन रीड

बिलकुल सही। "कुछ सौ" का आंकड़ा "बैच बैच बैच" पेपर से आता है - जिसने "एक 1GHz सीपीयू के 100% @ 25k बैचों" को सूचीबद्ध किया है। लेकिन वह कागज अब एक दशक पुराना है, और ड्राइवरों और सीपीयू ने तब से काफी सुधार किया है। मैं इसे (और मेरे अन्य) "कुछ हज़ार" पढ़ने के लिए अपडेट करूंगा।
एंड्रयू रसेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.