2012-05-18 23 views
8

मैं पहले पहले से ही समस्या यह है कि मैं की तरह कुछ कर रही द्वारा एक छवि इकाई में रंग मान मिश्रण करने के लिए करना चाहता था हो रही थी:जीएलएसएल, सेमफोर?

vec4 texelCol = imageLoad(myImage, myTexel); 
imageStore(myImage, myTexel, texelCol+newCol); 

परिदृश्य में कई टुकड़े 'myTexel' के लिए एक ही मूल्य है सकते हैं, जहां, इस aparently संभव नहीं है क्योंकि कोई छवि लोड और छवि के बीच परमाणुता नहीं बना सकता हैस्टोर कमांड और अन्य shaderinvocations texel रंग को बीच में बदल सकता है।

अब किसी ने मुझसे कहा कि poeple, uint बनावट पर परमाणु comands का उपयोग कर, ऐसी है कि शेडर Texel एक्सेस करने से पहले थोड़ी देर के पाश में किसी भी तरह इंतजार करेंगे और जैसे ही यह नि: शुल्क है संकेतबाहु बनाने के द्वारा इस समस्या को arround काम कर रहे हैं atomically अन्य टुकड़े शेडर आमंत्रणों को अवरुद्ध करने के लिए पूर्णांक बनावट लिखें, रंगीन पाठ को संसाधित करें और जब पूर्ण रूप से पूर्णांक पूर्णांक को समाप्त कर दें।

लेकिन मैं अपने दिमाग को इस बात पर नहीं देख सकता कि यह वास्तव में कैसे काम कर सकता है और यह कोड कैसा दिखता है?

क्या यह वास्तव में ऐसा करना संभव है? क्या एक जीएलएसएल टुकड़ा शेडर थोड़ी देर में प्रतीक्षा करने के लिए सेट किया जा सकता है? यदि यह संभव है, तो क्या कोई उदाहरण दे सकता है?

+0

[विस्तार विनिर्देश] से (http://www.opengl.org/registry/specs/EXT/shader_image_load_store.txt) ऐसा लगता है कि आपको उचित मेमोरी बाधाओं की व्यवस्था करने की आवश्यकता होगी, या तो 'मेमोरीबैरिएरएक्सटीटी) ('' या खुद को शेडर्स में 'मेमोरीबैरियर()'। – Flexo

+0

@awoodland: मेमोरी बाधाएं स्मृति को पढ़ने के लिए एक ही चरण में चल रहे अन्य शेडरों को अनुमति नहीं दे सकती हैं। –

+0

एनवीडिया केप्लर कार्ड पर जीएलएसएल सेमफोर समस्या के वर्तमान में काम करने वाले समाधान के लिए http://stackoverflow.com/a/16802075/1388799 पर मेरा उत्तर देखें। –

उत्तर

6

हां, आप यह कर सकते हैं, लेकिन केवल ऑर्डर जिसमें आइटम मिश्रित हैं, अप्रासंगिक है। अन्यथा आपको सामान्य तकनीकों का उपयोग करने की आवश्यकता है।

मूल रूप से आप केवल spinlock लागू कर रहे हैं। केवल एक लॉक चर के बजाय, आपके पास एक संपूर्ण बनावट के ताले के लायक हैं।

आपको पहली बार अपनी छवि की आकार की आवश्यकता है जिसे आप परमाणु संचालन के लिए उपयोग करेंगे। इसे GL_R32UI के साथ एक पूर्णांक बनावट होना चाहिए, और uimage मिलान के लिए r32ui का प्रारूप होना चाहिए। इसे 0 के साथ शुरू किया जाना चाहिए। परमाणु छवि और "मिश्रण" छवि दोनों को "सुसंगत" घोषित किया जाना चाहिए।

  1. परमाणु पूर्णांक छवि पर स्थान पर एक imageAtomicCompSwap कार्यवाही करें। आप इसे 0 से तुलना कर रहे हैं, और जिस मान को आप इसे सेट कर रहे हैं वह है 1.

  2. यदि # 1 1 लौटाता है, तो इसका मतलब है कि किसी और के पास लॉक है। चरण # 1 पर वापस जाएं।

  3. यदि # 1 0 लौटाता है, तो अब आपके पास टेक्क्सल तक विशेष पहुंच है (क्योंकि टेक्क्सल में अब इसमें 1 है, तुलना/स्वैप ऑपरेशन के लिए धन्यवाद)। जारी रहना।

  4. अपने मिश्रण ऑपरेशन करें। अपने मिश्रण ऑपरेशन के बाद memoryBarrier एमिट करें।

  5. 0 के मूल्य के साथ imageAtomicExchange प्रदर्शन करें। यह स्पिनलॉक को अनलॉक करता है।

कारण यह काम करता है एटोमिक्स के कारण है। जीएलएसएल सुनिश्चित करता है कि परमाणु परमाणु हैं। imageAtomicCompareSwap एक परमाणु अनुक्रम के रूप में एक पढ़ा/सशर्त-संशोधित/लेखन ऑपरेशन करता है। और क्योंकि यह परमाणु है, यह असंभव अन्य शेडर आमंत्रणों के लिए ऑपरेशन को रोक या बाधित करने के लिए है। इसका मतलब यह है कि इससे कोई फर्क नहीं पड़ता कि शेडर के कितने धागे चल रहे हैं: यदि उनमें से 100 imageAtomicCompareSwap(..., 0, 1) पर कॉल करते हैं, तो उनमें से एक को वापसी मूल्य के रूप में 1 प्राप्त होगा, और बाकी को 0 मिलेगा (उसी तकनीक के लिए, निश्चित रूप से)।

तो केवल एक धागा ताला मिलेगा; बाकी इंतजार करना चाहिए।

memoryBarrier() फ़ंक्शन का उपयोग यह सुनिश्चित करेगा कि अन्य धागे जो प्रतीक्षा कर रहे हैं, वे संशोधित डेटा उठाएंगे जब वे इसे पढ़ने के लिए जाएंगे। फिर, आपको उस छवि के लिए coherent क्वालीफायर का उपयोग करने की आवश्यकता है, जिसके साथ आप इसे कर रहे हैं।

+0

मुझे समझ में नहीं आता कि पूर्णांक बनावट स्क्रीन के आकार का क्यों होना चाहिए। इसका मतलब प्रति टुकड़ा एक ताला मूल्य होगा। लेकिन छवि के प्रति टेक्सल प्रति लॉक मूल्य नहीं होना चाहिए? – Mat

+1

@Mat: क्या स्क्रीन के पिक्सल की तुलना में छवि के अधिक टेक्स्ट हैं? यह इन चीजों को पहले से जानने में मदद करेगा। –

+0

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

संबंधित मुद्दे