यह ज्यामिति शेडर मेरे कार्यक्रम को इतना धीमा क्यों करता है?


27

मेरे पास एक OpenGL कार्यक्रम है, और मैं एक इलाके जाल प्रदान कर रहा हूं। मैं वर्टेक्स बफर में कोने को विस्थापित करता हूं और वास्तव में अभी तक उन्हें टुकड़े टुकड़े में रंग नहीं देता हूं। मैं एक बार में एक ज्यामिति shader को जोड़ रहा हूँ।

इससे पहले कि मैं ज्यामिति shader जोड़ा, जब मैं सिर्फ पाइपलाइन के टुकड़े और शीर्ष छायांकन चरणों प्रोग्रामिंग कर रहा था, मैं लगभग 30+ के framerates हो रही थी। पर्याप्त है कि मैं किसी भी तड़प को नोटिस नहीं कर सका। जियोमेट्री शेडर को जोड़ने के बाद, मुझे प्रति सेकंड लगभग 5 फ्रेम मिलते हैं। क्यूं कर? यह ज्यामिति shader की संपूर्णता है:

#version 420

layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;

void main()
{
    for (int i = 0; i < gl_in.length(); i++)
    {
        gl_Position = gl_in[i].gl_Position;
        EmitVertex();
    }
    EndPrimitive();
}

क्या यह बिल्कुल वैसा ही नहीं है जैसा कि OpenGL ज्योमेट्री शेडर के बिना कर रहा था?

जवाबों:


40

क्या यह बिल्कुल वैसा ही नहीं है जैसा कि OpenGL ज्योमेट्री शेडर के बिना कर रहा था?

नहीं, यह नहीं है। जीएस एक वैकल्पिक कदम है, न कि एक ऐसा कदम जिसका डिफ़ॉल्ट है।

OpenGL के लिए एक ज्यामिति shader को निष्पादित करने के लिए , उसे " प्राइमरी असेंबली " के रूप में जाना जाता है । जब आप के माध्यम से त्रिकोणों की एक श्रृंखला प्रस्तुत करते हैं GL_TRIANGLE_STRIP, तो ओपनजीएल प्रत्येक 3 आसन्न कोने को एक व्यक्तिगत त्रिकोण में बदलने के लिए आंतरिक सामान करेगा, घुमावदार आदेश को उचित रूप से संशोधित करेगा।

आम तौर पर, जब जीएस का उपयोग नहीं किया जाता है, तो यह प्रक्रिया एक बार की जाती है। जब आप एक जीएस का उपयोग करते हैं, तो जीएस निष्पादित होने से पहले इसे निष्पादित किया जाना चाहिए। लेकिन यह जीएस के बाद भी किया जाना चाहिए , क्योंकि एक जीएस पूरी तरह से अलग-अलग आदिम प्रकार (जैसे क्वाड्स) का उत्पादन कर सकता है।

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

इसके अलावा, जीएस की उपस्थिति में कई अनुकूलन अब कार्य नहीं करते हैं। अनुक्रमित प्रतिपादन पर विचार करें।

एलिमेंट एरे बफर से प्रत्येक इंडेक्स एक वर्टेक्स शडर से एक ही आउटपुट उत्पन्न करेगा। इसलिए GPU अक्सर इन आउटपुट को T-L & L कैश में कैश कर देगा । यदि यह एक सूचकांक देखता है जो पहले से ही कैश में है, तो वीएस फिर से नहीं चलाया जाता है; यह सिर्फ कैश से डेटा प्राप्त करता है।

यह क्या है"? "यह" ... आदिम विधानसभा इकाई है । हाँ, वह चीज़ जो जीएस का उपयोग करने पर दो बार चलती है। सूचकांक कैशिंग सामान? यह केवल GS के इनपुट के लिए काम करता है ।

तो जीएस के आउटपुट का क्या होता है? खैर, यह हार्डवेयर निर्भर है। लेकिन इसे किसी तरह के मेमोरी बफर में जाना पड़ता है। और इस समस्या में निहित है: कि बफर बिल्कुल अनुक्रमित नहीं है। यह एक GlDrawArrays स्थिति की तरह है।

इसलिए यदि आप एक इंडेक्स बफर भेजते हैं 0, 1, 2, 0, 2, 3, तो यह टी-एंड-एल कैश में 4 कोने में बदल जाएगा। लेकिन पोस्ट-जीएस बफर के वर्टिक्स में अब 6 वर्टिकल हैं। जीएस बफर के बाद का स्थान अधिक स्थान का उपयोग करता है। इसलिए यदि आप टी-एंड-एल अनुकूलित त्रिकोण सूची या स्ट्रिप्स को ठीक से बनाने की परेशानी से गुज़रते हैं, और आप जैसे पास से गुज़रते हुए जीएस पर फ़्लिप करते हैं, तो आप मूल रूप से उस अनुकूलन से अपने प्रदर्शन लाभ का लगभग आधा हिस्सा मार देते हैं।

यह बेकार नहीं था, लेकिन यह चोट करता है।

इस तथ्य को जोड़ना यह है कि कई जीएल 3.x-क्लास जीपीयू (उर्फ: डीएक्स 10) में छोटे पोस्ट-जीएस बफर थे। छोटे बफर, कम जीएस इनवोकेशन आप एक साथ सक्रिय हो सकते हैं। इसलिए आपका हार्डवेयर जीएस पर प्रभावी रूप से अड़चन है। चूँकि tessellation 4.x क्लास हार्डवेयर की एक बड़ी विशेषता है, ऐसे अधिकांश हार्डवेयर में भारी GS उपयोग को व्यवहार्य बनाने के लिए पर्याप्त बफर होते हैं।

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

जीएस-प्रेरित मंदी के बारे में अधिक जानकारी के लिए, इस लेख को पढ़ें

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

इसके सामान्य अपवाद हैं:


मैं प्रत्येक बहुभुज की ऊँचाई को उसकी उच्चतम ऊँचाई पर ले जाकर उसकी न्यूनतम ऊँचाई घटाकर गणना करने की कोशिश कर रहा हूँ। हालांकि, अगर एक ज्यामिति shader आवश्यक रूप से मुझे इस राशि से धीमा कर देगा, मुझे लगता है कि मैं इसे रचनात्मक रूप से वर्टेक्स shader में करने में सक्षम हो सकता हूं।
अवी

1
@Avi ध्यान दें कि एक त्रिकोण में उच्चतम और निम्नतम बिंदु आपको इसकी स्थिरता नहीं देंगे; आपको तीनों बिंदु चाहिए।
सैम होसेवर ३१'१३

2
व्यक्तिगत रूप से मुझे हमेशा GS के मुकाबले पॉइंट स्प्राइट्स के लिए अधिक उपयोगी इंस्टेंसिंग मिली है।
मैक्सिमस मिनिमस

1
क्या बिंदु के अपवाद को सामान्य करने के लिए छिड़कता है layout(points) in;? या यह निश्चित उत्पादन आकार है? या शायद दोनों?
फिलिप १
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.