GLSL - मुख्य फ़ंक्शन स्कोप के बाहर वैश्विक चर घोषित करना


12

क्या यह GLSL में आपके मुख्य फंक्शन स्कोप के बाहर वेरिएबल घोषित करने में मदद करता है? क्या इन चरों का वास्तव में पुन: उपयोग होता है और क्या यह अधिक कुशल है?

यहाँ प्रश्न में कोड है:

varying vec2 vposition;
uniform float seed;
uniform float top;
uniform float bottom;
uniform float phi;
uniform float theta;
uniform float scaledPI;
uniform float yn;
uniform float ym;
uniform float rx;
uniform float ry;
uniform float radius;

const float PI = 3.141592653589793238462643383;

float left;
float right;
float mscaled;
float xn;
float xm;
void main() {
    float t = vposition.y * yn + ym;

    if(t <= 0.0 || t >= PI){
        left = phi - PI;
        right = phi + PI;
    }else{
        mscaled = scaledPI / (1 - abs(Math.cos(theta)));
        mscaled = mscaled < PI ? mscaled : PI;
        left = phi - mscaled;
        right = phi + mscaled;
    }
    xn = (left - right) / ((-rx / 2.0) - (rx / 2.0));
    xm = left - ((-rx/2.0) * xn);
    float p = vposition.x * xn + xm;

    vec3 coords = vec3( sin(p) * sin(t), cos(t), cos(p) * sin(t) );
    float nv = surface( vec4( coords, seed ) );
    gl_FragColor = vec4( vec3( nv, nv, nv ), 1.0 );
}

3
यह सवाल भ्रामक है। GLSL में मुख्य लूप नहीं होता है। क्या आपका मतलब main()फंक्शन से है? क्या आपके मूल्य वास्तव में वैश्विक चर (GLSL parlance में वर्दी या विशेषता) या निरंतर मूल्य हैं?
सीन मिडिलिच

क्या आप कुछ कोड पोस्ट कर सकते हैं जो आप बात कर रहे हैं?
नाथन रीड

मैंने प्रश्न को कोड के साथ अद्यतन किया।
रॉगरडॉगर

@ user1286792: यह इस तथ्य को नहीं बदलता है कि GLSL का मुख्य लूप नहीं है । यह स्पष्ट नहीं है कि आप किस बारे में बात कर रहे हैं। वास्तव में आप क्या सोच रहे हैं ऐसा करने से बच जाएंगे?
निकोल बोल

@NicolBolas मैंने प्रश्न को अधिक स्पष्ट होने के लिए अद्यतन किया है। उम्मीद है कि यह भविष्य में किसी के लिए अब उपयोगी है।
RodgerDodger

जवाबों:


33

मुझे लगता है कि मुझे वही मिल रहा है जो आप पूछना चाहते हैं। मुझे लगता है कि आपकी प्राथमिक चिंता गैर-समान रूप से परिभाषित चर हैं 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 पर। मैं भी हर संभव मामले में हर "चर" कास्ट बनाने की सिफारिश करेंगे। यह फिर से कुछ कम-सक्षम कंपाइलरों को संकेत दे सकता है कि कुछ अनुकूलन संभव हैं, और इससे भी महत्वपूर्ण बात यह है कि यह आपके कोड को अधिक स्व-दस्तावेजीकरण और बनाए रखने में आसान बनाता है।

और निश्चित रूप से, यहां आपकी अनिवार्य "परीक्षण करने के लिए प्रोफाइल और निश्चित" सलाह के लिए पता लगाना है। अपने ग्लोबल्स के साथ और उसके बिना अपने शेडर को लिखें और इसे प्रोफाइल करें। ऑनलाइन और किसी भी प्रदर्शन की सलाह को अविश्वास और मान लिया जाना चाहिए कि या तो उसे दबा दिया गया है या तारीख से बाहर कर दिया गया है।


मेरा वास्तव में यही मतलब है। आपने मेरे प्रश्न का पूरी तरह से उत्तर दिया और यह भी बेहतर बताया कि मैं क्या पूछ रहा था।
RodgerDodger

1
वास्तव में कभी-कभी गैर-कांस्ट के बजाय एरेज़ को कास्ट घोषित करने से पूरे shader को धीमा (A LOT धीमा) बना देता है। मैंने उस समस्या को अपने GTX 460 पर देखा।
तारा 16

मुझे बस एक अजीब त्रुटि से छुटकारा मिला और दृढ़ता से संदेह था कि यह एक एड्रेनो जीपीयू (ओपनजीएल ईएस 3.1) एक शेडर को संकलित करने में विफल रहा क्योंकि चर मुख्य के बाहर घोषित किए गए थे।
कोमोडोरो

सबसे गहन एसओ उत्तरों में से एक मैंने कभी देखा है - अच्छी तरह से किया गया!
duhaime

आज मैं कुछ नया सीखता हूं। आज, मैं सीखता हूं, मैं वास्तव में glsl को नहीं जानता या समझता नहीं हूं। सिर्फ इसलिए कि मैं इसका उपयोग करने के लिए उपयोग कर सकते हैं बनाने के लिए साइबर स्पेस बदल ज्यामिति gif का मतलब यह नहीं है कि मैं समझता हूं कि यह कैसे काम करता है।
कैरमंगु
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.