मुझे लगता है कि मुझे वही मिल रहा है जो आप पूछना चाहते हैं। मुझे लगता है कि आपकी प्राथमिक चिंता गैर-समान रूप से परिभाषित चर हैं main()
:
float left;
float right;
float mscaled;
float xn;
float xm;
आइए नज़र डालते हैं कि GPU और GLSL कैसे काम करते हैं। GPU में स्टैक या कॉल सक्रियण रिकॉर्ड नहीं है। जीएलएसएल में स्कोप या लोकल वैरिएबल्स को सिम करने का एक तरीका नहीं है जैसे कि एक सी कंपाइलर अधिकांश सीपीयू पर कर सकता है। वे सभी मौजूद हैं जो रजिस्टर हैं, जो या तो एकरूप रजिस्टर, शेडर चरण इनपुट, आउटपुट, और स्थानीय रजिस्टर फ़ाइल उस shader मंगलाचरण के लिए अद्वितीय हैं।
दूसरे शब्दों में, जैसे कि फंक्शन या स्टैक या हीप जैसी कोई चीज नहीं होती है, सभी वेरिएबल कहीं भी एक रजिस्टर में रहते हैं। चाहे वे GLSL में कुछ दायरे के लिए स्थानीय हों या पूरी फ़ाइल में वैश्विक कोई फर्क नहीं पड़ता। वे सिर्फ रजिस्टर कर रहे हैं।
हालांकि, रजिस्टर एलोकलेटर जीएलएसएल मानक का हिस्सा नहीं है। जब जीपीयू समझता है तो निम्न-स्तर की मशीन कोड में उच्च-स्तरीय GLSL कोड को परिवर्तित करने के लिए अलग-अलग OpenGL कार्यान्वयन में गुणवत्ता के विभिन्न स्तर हो सकते हैं। एक कंपाइलर (GLSL या अन्यथा) के अधिक जटिल भागों में से एक रजिस्टर आवंटन है । यह कंपाइलर का वह हिस्सा है जो निर्धारित करता है कि कौन सा दिया गया वेरिएबल रजिस्टर करता है। C यह थोड़ा कठिन है क्योंकि इसे आमतौर पर बहुत छोटे रजिस्टर फाइलों (विशेष रूप से x86) से निपटना पड़ता है और इसे रजिस्टर स्पिलिंग (स्टैक के लिए चर चलना) और अलियासिंग (कॉलिंग कार्यों से पहले रैम के लिए चर वापस सहेजना) से निपटना पड़ता है विषम निर्देश जो आउटपुट की मांग करते हैं एक विशेष रजिस्टर (x86's) में हैंidiv
उदाहरण के लिए)। GPU में ढेर-ढेर या ढेर होने के कारण एक बड़ी-ish रजिस्टर फ़ाइल होती है, इसलिए आवंटनकर्ता सरल हो सकता है।
हालाँकि, रजिस्टर फ़ाइल अनंत नहीं है। यदि आपके पास आपके हार्डवेयर द्वारा समर्थित रजिस्टरों की तुलना में अधिक चर हैं तो कंपाइलर को रजिस्टरों में आपके सभी चर फिट करने का प्रयास करना होगा। इसके लिए आमतौर पर कुछ प्रकार की लाइनिंग रेंज की जाँच की आवश्यकता होती है । यही है, यदि आप xn
एक गणना के लिए एक चर का उपयोग करते हैं, तो इसे फिर से कभी भी उपयोग न करें, संकलक यह निर्धारित कर सकता है और फिर जान सकता है कि कब्जे वाले रजिस्टर को xn
बाद में किसी अन्य चर द्वारा उपयोग किया जा सकता है, इस प्रकार रजिस्टरों की तुलना में अधिक चर की अनुमति है (इसलिए लंबे समय तक के रूप में एक बार में बहुत सारे जीवित चर नहीं हैं)।
कंपाइलर हालांकि ऐसा नहीं कर सकता है। यह नहीं है। या यह केवल कुछ मामलों में ही हो सकता है। सरल किए गए स्कोप्स हल करने के लिए बहुत आसान समस्या का संकलन करते हैं। स्थानीय फ़ंक्शन चर के लिए आवंटित सभी रजिस्टर को उस फ़ंक्शन के बाहर निकलने के बाद पुन: उपयोग किया जा सकता है क्योंकि यह जानता है कि चर मृत हैं। वैश्विक चर के पास ऐसी कोई आसान गारंटी नहीं है। इसलिए, कुछ कम सक्षम कंपाइलर अपने जीवनकाल को भी अनुकूलित नहीं कर सकते हैं, और वैश्विक चर हमेशा एक रजिस्टर खाएंगे। यह कुछ भी धीमा नहीं करेगा, लेकिन यह कुछ ड्राइवरों पर आपके द्वारा लिखे जाने वाले आकार के आकार को सीमित कर सकता है।
सामान्य तौर पर, मैं सभी चर को स्थानीयकृत रखने की अत्यधिक सलाह दूंगा। चर के उपयोग के रूप में परिभाषा को समझ में आता है। यह सभी प्रोग्रामिंग भाषाओं पर लागू होता है, न कि केवल GLSL पर। मैं भी हर संभव मामले में हर "चर" कास्ट बनाने की सिफारिश करेंगे। यह फिर से कुछ कम-सक्षम कंपाइलरों को संकेत दे सकता है कि कुछ अनुकूलन संभव हैं, और इससे भी महत्वपूर्ण बात यह है कि यह आपके कोड को अधिक स्व-दस्तावेजीकरण और बनाए रखने में आसान बनाता है।
और निश्चित रूप से, यहां आपकी अनिवार्य "परीक्षण करने के लिए प्रोफाइल और निश्चित" सलाह के लिए पता लगाना है। अपने ग्लोबल्स के साथ और उसके बिना अपने शेडर को लिखें और इसे प्रोफाइल करें। ऑनलाइन और किसी भी प्रदर्शन की सलाह को अविश्वास और मान लिया जाना चाहिए कि या तो उसे दबा दिया गया है या तारीख से बाहर कर दिया गया है।
main()
फंक्शन से है? क्या आपके मूल्य वास्तव में वैश्विक चर (GLSL parlance में वर्दी या विशेषता) या निरंतर मूल्य हैं?