इस साइट की सामग्री का अनुवाद कृत्रिम बुद्धिमत्ता (AI) या मशीन अनुवाद तकनीक का उपयोग करके किया गया है, और इसमें त्रुटियाँ हो सकती हैं.

Skip to content

मेटल के 3 साल

तीन साल पहले, हमने अपने रेंडरर को मेटल पर पोर्ट किया था। इसमें ज्यादा समय नहीं लगा, यह बहुत मज़ेदार था और iOS पर यह वाकई बहुत अच्छा काम करता था। इसलिए हमने एक लेख लिखा जिसमें बताया गया कि हमने यह निर्णय कैसे लिया और इसका नतीजा क्या रहा (स्पॉइलर: वाकई बहुत अच्छा!)। उस मूल रेट्रोस्पेक्टिव का ज़्यादातर हिस्सा आज भी लागू होता है, लेकिन आज मेटल पहले से कहीं बेहतर स्थिति में है – इसलिए हमने इसे अपने तीन साल के अपडेट के साथ फिर से प्रकाशित करने का फैसला किया है।

तो आइए समय में पीछे चलते हैं, मान लीजिए कि दिसंबर 2016 है और हमने अभी-अभी iOS पर अपने मेटल रेंडरर का एक संस्करण जारी किया है।

मेटल ही क्यों?

जब 2014 में WWDC में Apple ने Metal की घोषणा की, तो मेरी शुरुआती प्रतिक्रिया इसे अनदेखा करने की थी। यह केवल सबसे नए हार्डवेयर पर उपलब्ध था जो हमारे अधिकांश उपयोगकर्ताओं के पास नहीं था, और जबकि Apple ने कहा कि यह CPU प्रदर्शन की समस्याओं को हल करता है, सबसे छोटे बाज़ार के लिए अनुकूलन करने का मतलब होगा कि सबसे तेज़ और सबसे धीमी डिवाइस के बीच का अंतर और भी बढ़ जाएगा। उस समय हम Apple पर केवल OpenGL ES 2 चला रहे थे, और Android पर पोर्ट करना भी शुरू कर रहे थे।

ढाई साल बाद, हमारे उपयोगकर्ताओं के लिए मेटल का बाज़ार हिस्सेदारी इस प्रकार दिखती है:

यह पहले की तुलना में कहीं अधिक आकर्षक है। अभी भी Metal को लागू करने से सबसे पुराने उपकरणों को कोई मदद नहीं मिलती, लेकिन iOS पर GL बाजार लगातार सिकुड़ रहा है, और इन पुराने उपकरणों पर हम जो सामग्री चलाते हैं वह अक्सर नवीनतम उपकरणों पर चलने वाली सामग्री से अलग होती है, इसलिए इसे तेज़ बनाने के लिए कुछ प्रयास करना समझदारी है। चूंकि आपका iOS Metal कोड बहुत कम बदलाव के साथ Mac पर चलेगा, इसलिए इसे Mac पर भी उपयोग करना समझदारी हो सकती है, भले ही आप मोबाइल-केंद्रित हों (हम वर्तमान में केवल iOS पर Metal बिल्ड प्रदान करते हैं)।

मुझे लगता है कि बाज़ार हिस्सेदारी का थोड़ा और विस्तार से विश्लेषण करना सार्थक है। iOS पर, हम iOS 8.3+ के लिए मेटल का समर्थन करते हैं; हालाँकि कुछ उपयोगकर्ता OS संस्करण प्रतिबंधों के कारण मेटल नहीं चला सकते, लेकिन जो 25% उपयोगकर्ता अभी भी GL चला रहे हैं, उनमें से अधिकांश बस पुराने डिवाइस का उपयोग कर रहे हैं जिनमें SGX हार्डवेयर है। उनमें OpenGL ES 3 की कोई सुविधाएँ भी नहीं हैं, और हम वहाँ एक कम-स्तरीय रेंडरिंग पाथ चलाने से संतुष्ट हैं (हालाँकि हम चाहेंगे कि सभी डिवाइस मेटल का उपयोग करें - सौभाग्य से GL/मेटल का विभाजन और बेहतर होगा)। मैक पर, मेटल एपीआई नया है और ओएस (OS) एक बहुत महत्वपूर्ण भूमिका निभाता है - मेटल का उपयोग करने के लिए आपको OSX 10.11+ का उपयोग करना होगा और हमारे आधे उपयोगकर्ताओं के पास बस एक पुराना ओएस है - यह हार्डवेयर से कम और सॉफ्टवेयर से अधिक जुड़ा हुआ है (हमारे 95% मैक उपयोगकर्ता ओपनजीएल 3.2+ का उपयोग करते हैं)।

तो बाज़ार हिस्सेदारी को देखते हुए, हमारे पास अभी भी ऐसे विकल्प हैं जिनमें मेटल पर पोर्ट करना शामिल नहीं है। उनमें से एक है बस मोल्टेनजीएल का उपयोग करना, जो हमारे पास पहले से मौजूद ओपनजीएल कोड का उपयोग करेगा, लेकिन कथित तौर पर तेज़ होगा; दूसरा है वल्कन पर पोर्ट करना (पीसी पर बेहतर प्रदर्शन पाने के लिए, और अंततः एंड्रॉइड पर भी) और मोल्टेनवीके का उपयोग करना। मैंने संक्षेप में MoltenGL का मूल्यांकन किया है और मैं इसके परिणामों से बहुत उत्साहित नहीं था - हमारे कोड को चलाने में कुछ मेहनत लगी, और जबकि प्रदर्शन स्टॉक OpenGL की तुलना में थोड़ा बेहतर था, मैं इससे और अधिक की उम्मीद कर रहा था। जहाँ तक MoltenVK की बात है, मुझे लगता है कि एक लो-लेवल API को दूसरे के ऊपर एक परत के रूप में लागू करने की कोशिश करना एक भ्रामक कदम है - आपको अवश्य ही इम्पीडेंस मिसमैच (impedance mismatch) का सामना करना पड़ेगा, जिसके परिणामस्वरूप प्रदर्शन अनुकूल नहीं होगा - हो सकता है कि यह उस हाई-लेवल API से बेहतर हो जिसे आप पहले इस्तेमाल करते थे, लेकिन इसके अधिकतम संभव तेज़ होने की संभावना नहीं है, और कथित तौर पर यही कारण है कि आप शुरू में ही एक लो-लेवल API चुन रहे हैं! एक और महत्वपूर्ण पहलू यह है कि मेटल का कार्यान्वयन वल्कन की तुलना में बहुत सरल है - इस पर बाद में और बात करेंगे - इसलिए एक तरह से मैं वल्कन -> मेटल के बजाय मेटल -> वल्कन रैपर को प्राथमिकता दूँगा।

यह ध्यान देने योग्य भी है कि जाहिर तौर पर नए iPhones पर iOS 10 में कोई GL ड्राइवर नहीं है - GL को Metal के ऊपर लागू किया गया है। जिसका मतलब है कि OpenGL का उपयोग करना वास्तव में आपको केवल थोड़ी सी विकास की मेहनत बचाता है - इतनी भी नहीं, यह देखते हुए कि OpenGL का "एक बार लिखें, कहीं भी चलाएं" का वादा मोबाइल पर वास्तव में काम नहीं करता है।

पोर्टिंग

कुल मिलाकर, Metal में पोर्ट करना बहुत आसान था। हमारे पास विभिन्न ग्राफिक्स APIs के साथ काम करने का बहुत अनुभव है, जिसमें Direct3D 9/11 जैसे उच्च स्तरीय APIs से लेकर PS4 GNM जैसे निम्न स्तरीय APIs तक शामिल हैं। यह एक अनूठा लाभ देता है कि हम आराम से Metal जैसे API का उपयोग कर सकते हैं जो एक ही समय में काफी हद तक उच्च स्तरीय है, लेकिन साथ ही CPU-GPU सिंक्रनाइज़ेशन जैसे कुछ कार्य ऐप डेवलपर के लिए करने के लिए छोड़ देता है।

वास्तव में एकमात्र बाधा हमारे शेडर्स को कंपाइल करवाना था - एक बार यह हो जाने के बाद और कोड लिखने का समय आने पर यह स्पष्ट हो गया कि एपीआई इतना सरल और स्व-स्पष्ट है कि कोड लगभग अपने आप ही लिखा गया। मैंने उस पोर्ट को, जो ज़्यादातर चीज़ों को एक अनुकूल-न-होने वाले तरीके से रेंडर कर रहा था, लगभग 10 घंटों में एक ही दिन में चला दिया, और फिर दो और हफ़्ते कोड को साफ़ करने, सत्यापन संबंधी समस्याओं को ठीक करने, प्रोफाइलिंग और ऑप्टिमाइज़ करने और सामान्य सुधार करने में बिताए। इस समय-सीमा में एक API कार्यान्वयन प्राप्त करना, API और टूलसेट की गुणवत्ता के बारे में बहुत कुछ कहता है। मेरा मानना है कि इसमें कई पहलू योगदान करते हैं:

  • आप हर चरण में अच्छे फीडबैक के साथ, कोड को क्रमबद्ध तरीके से विकसित कर सकते हैं। हमारा कोड शुरुआत में सभी CPU-GPU सिंक्रोनाइज़ेशन को अनदेखा करता था, स्टेट सेटअप के कुछ हिस्सों में बहुत ही अनुकूल नहीं था, संसाधनों के लिए अंतर्निहित संदर्भ ट्रैकिंग का उपयोग करता था और समस्याओं से बचने के लिए कभी भी CPU और GPU को समानांतर रूप से नहीं चलाता था; फिर ऑप्टिमाइज़ेशन/पॉलिश चरण ने इसे कुछ ऐसा में बदल दिया जिसे हम शिप कर सकते थे, और इस प्रक्रिया में रेंडर करने की क्षमता कभी नहीं खोई।
  • टूल्स आपके लिए उपलब्ध हैं, वे काम करते हैं और वे अच्छी तरह से काम करते हैं। यह उन लोगों के लिए उतना आश्चर्य की बात नहीं है जो Direct3D 11 के आदी हैं - लेकिन यह मोबाइल पर पहली बार था जब मेरे पास एक CPU प्रोफाइलर, एक GPU प्रोफाइलर, एक GPU डिबगर और एक GPU API वैलिडेशन लेयर थी, जो सभी एक साथ अच्छी तरह से काम करते थे, विकास के दौरान अधिकांश समस्याओं को पकड़ते थे और कोड को अनुकूलित करने में मदद करते थे।
  • हालांकि यह एपीआई Direct3D 11 से कुछ हद तक निचले स्तर की है, और यह कुछ प्रमुख निम्न-स्तरीय निर्णय डेवलपर पर छोड़ देती है (जैसे कि रेंडर पास कॉन्फ़िगरेशन या सिंक्रनाइज़ेशन), फिर भी यह एक पारंपरिक संसाधन मॉडल का उपयोग करती है जहाँ प्रत्येक संसाधन में कुछ "उपयोग फ़्लैग" होते हैं जिनके साथ इसे बनाया गया है, लेकिन इसके लिए पाइपलाइन बैरियर या लेआउट ट्रांज़िशन की आवश्यकता नहीं होती है, और एक पारंपरिक बाइंडिंग मॉडल जहाँ प्रत्येक शेडर चरण में कई स्लॉट होते हैं जिनमें आप स्वतंत्र रूप से संसाधनों को असाइन कर सकते हैं। ये दोनों परिचित हैं, इन्हें समझना आसान है और तेज़ी से काम शुरू करने के लिए इनमें बहुत कम कोड की आवश्यकता होती है।

एक और चीज़ जिसने मदद की वह यह है कि हमारा एपीआई इंटरफ़ेस मेटल-जैसे एपीआई के लिए तैयार था - यह बहुत ही संक्षिप्त है लेकिन यह पर्याप्त विवरण (जैसे रेंडर पास) प्रदर्शित करता है ताकि एक कुशल कार्यान्वयन को आसानी से लिखा जा सके। हमारे कार्यान्वयन में किसी भी समय मुझे स्थिति (स्टेट) को सहेजने/पुनर्स्थापित करने (बहुत से एपीआई इंटरफ़ेस इससे पीड़ित हैं, विशेष रूप से रेंडर टारगेट सेटअप को स्थिति परिवर्तन के रूप में मानने और संसाधन/स्थिति बाइंडिंग के उस दौरान बने रहने के कारण) या संसाधन के जीवनकाल/सिंक्रनाइज़ेशन के बारे में जटिल निर्णय लेने की आवश्यकता नहीं पड़ी। रेंडर करने के लिए ज़रूरी लगभग एकमात्र "जटिल" कोड वह है जो रेंडर पाइपलाइन स्टेट बनाने के लिए ज़रूरी बिट्स को हैश करके स्टेट बनाता है - पाइपलाइन स्टेट ऑब्जेक्ट हमारे API एब्स्ट्रैक्शन का हिस्सा नहीं हैं। वह भी काफी सीधा-सादा और तेज़ है। मैं हमारे API इंटरफ़ेस के बारे में एक अलग पोस्ट में और लिखूँगा।

तो, शेडर्स को कंपाइल करने में एक हफ्ता, एक परिष्कृत और अनुकूलित कार्यान्वयन1 तैयार करने में दो हफ्ते – परिणाम क्या हैं? परिणाम शानदार हैं – मेटल प्रदर्शन के वादे को पूरी तरह से पूरा करता है। एक तो, सिंगल थ्रेडेड डिस्पैच प्रदर्शन OpenGL की तुलना में स्पष्ट रूप से बेहतर है (कार्यभार के आधार पर हमारे रेंडर फ्रेम के ड्रॉ डिस्पैच हिस्से को 2-3 गुना तक छोटा कर रहा है), और यह इस तथ्य के बावजूद है कि हमारा OpenGL कार्यान्वयन अनावश्यक स्टेट सेटअप को कम करने और फास्ट पाथ का उपयोग करके ड्राइवर के साथ बेहतर तालमेल बिठाने के मामले में काफी अच्छी तरह से ट्यून किया गया है। लेकिन यह यहीं नहीं रुकता - Metal में मल्टीथ्रेडिंग का उपयोग करना बहुत आसान है, बशर्ते आपका रेंडरिंग कोड इसके लिए तैयार हो। हमने अभी तक थ्रेडेड ड्रॉ डिस्पैच पर स्विच नहीं किया है, लेकिन हम पहले से ही संसाधनों को तैयार करने वाले कुछ अन्य हिस्सों को रेंडर थ्रेड से अलग करके चलाने के लिए परिवर्तित कर रहे हैं, जो OpenGL के विपरीत, काफी हद तक सहज है।

इसके अलावा, मेटल हमें आसानी से सुलभ और विश्वसनीय उपकरण देकर कुछ अन्य प्रदर्शन समस्याओं को ठीक करने की अनुमति देता है। हमारे रेंडरिंग कोड का एक केंद्रीय हिस्सा वह सिस्टम है जो CPU पर वर्ल्ड स्पेस में लाइटिंग डेटा की गणना करता है और इसे 3D टेक्सचर के क्षेत्रों में अपलोड करता है (जिसे हमें OpenGL ES 2 हार्डवेयर पर एमुलेट करना पड़ता है)। अपडेट आंशिक हैं इसलिए हम पूरी टेक्सचर को डुप्लिकेट नहीं कर सकते और हमें इस बात पर निर्भर रहना पड़ता है कि ड्राइवर glTexSubImage3D को कैसे लागू करता है। एक समय पर हमने अपडेट प्रदर्शन को बेहतर बनाने के लिए PBO का उपयोग करने की कोशिश की, लेकिन एंड्रॉइड और iOS दोनों पर, हर जगह महत्वपूर्ण स्थिरता समस्याओं का सामना करना पड़ा। मेटल पर एक क्षेत्र को अपलोड करने के दो अंतर्निहित तरीके हैं - MTLTexture.replaceRegion जिसका उपयोग आप तब कर सकते हैं जब GPU वर्तमान में टेक्सचर को नहीं पढ़ रहा है, या MTLBlitCommandEncoder (copyFromBufferToTexture या copyFromTextureToTexture) जो क्षेत्र को एसिंक्रोनसली अपलोड कर सकता है, ठीक उसी समय जब GPU टेक्सचर का उपयोग शुरू कर सकता है।

ये दोनों तरीके मेरी अपेक्षा से धीमे थे - पहला वास्तव में उपलब्ध नहीं था क्योंकि हमें कुशल आंशिक अपडेट का समर्थन करना था, और यह पूरी तरह से CPU पर काम करता था, जिसमें पता चला कि इसका पता अनुवाद कार्यान्वयन बहुत धीमा था। दूसरा काम तो करता था लेकिन ऐसा लगता था कि यह 3D टेक्सचर भरने के लिए 2D ब्लिट्स की एक श्रृंखला का उपयोग कर रहा था, जो CPU की ओर से कमांड सेट करने में काफी महंगी थीं और किसी भी कारण से GPU पर भी बहुत अधिक ओवरहेड रखती थीं। अगर यह ओपनजीएल होता तो बात खत्म हो जाती - वास्तव में, इन दो तरीकों का प्रदर्शन ओपनजीएल में इसी तरह के अपडेट की देखी गई लागत से लगभग मेल खाता था। सौभाग्य से, मेटल होने के कारण, इसमें कंप्यूट शेडर्स तक आसान पहुंच है - और एक बहुत ही सरल कंप्यूट शेडर ने हमें एक बफ़र -> 3डी टेक्सचर अपलोड करने की क्षमता दी जो सीपीयू और जीपीयू दोनों पर बहुत तेज़ था और मूल रूप से कोड के इस हिस्से में हमारी प्रदर्शन समस्याओं को हमेशा के लिए हल कर दिया2:

अंतिम सामान्य टिप्पणी के रूप में, Metal कोड का रखरखाव भी काफी हद तक सहज है - अब तक हमें जो भी अतिरिक्त सुविधाएँ जोड़नी पड़ीं, उन्हें वहाँ जोड़ना हमारे द्वारा समर्थित किसी भी अन्य API की तुलना में आसान था, और मुझे उम्मीद है कि यह प्रवृत्ति जारी रहेगी। एक चिंता थी कि एक और API जोड़ने के लिए निरंतर रखरखाव की आवश्यकता होगी, लेकिन OpenGL की तुलना में इसके लिए वास्तव में ज्यादा काम की जरूरत नहीं है; वास्तव में, चूंकि हमें अब iOS पर OpenGL ES 3 का समर्थन नहीं करना है, इसका मतलब है कि हम अपने कुछ OpenGL कोड को भी सरल बना सकते हैं।

स्थिरता

आज iOS पर मेटल बहुत स्थिर लगता है। मुझे यकीन नहीं है कि 2014 में लॉन्च के समय स्थिति कैसी थी, या आज मैक पर यह कैसी है, लेकिन iOS के लिए ड्राइवर और टूल दोनों काफी ठोस लगते हैं।

iOS 10 पर हमें एक ड्राइवर समस्या हुई थी जो Xcode 7 से संकलित शेडर्स को लोड करने से संबंधित थी (जिसे हमने Xcode 8 पर स्विच करके ठीक किया), और iOS 9 पर एक ड्राइवर क्रैश हुआ था जो nextDrawable API के दुरुपयोग का परिणाम निकला। इसके अलावा हमने कोई व्यवहारिक बग या कोई क्रैश नहीं देखा है - एक अपेक्षाकृत नए API के लिए मेटल हर मामले में बहुत ठोस रहा है।

इसके अतिरिक्त, मेटल के साथ मिलने वाले टूल्स विविध और समृद्ध हैं; विशेष रूप से, आप उपयोग कर सकते हैं:

  • एक काफी व्यापक सत्यापन परत जो API का उपयोग करने में सामान्य समस्याओं की पहचान करती है। यह मूल रूप से Direct3D डिबग की तरह है - जो Direct3D के लिए तो परिचित है लेकिन OpenGL की दुनिया में लगभग अज्ञात है (सिद्धांत में ARB_debug_callback को यह हल करना चाहिए, व्यवहार में यह ज्यादातर अनुपलब्ध है और जब उपलब्ध होता भी है, तो बहुत मददगार नहीं होता)
  • एक कार्यशील GPU डिबगर जो आपके द्वारा भेजी गई सभी कमांड्स को उनकी स्थिति, रेंडर टारगेट की सामग्री, टेक्सचर की सामग्री आदि के साथ दिखाता है। मुझे नहीं पता कि इसमें एक कार्यशील शेडर डिबगर है या नहीं क्योंकि मुझे इसकी कभी ज़रूरत नहीं पड़ी, और बफ़र निरीक्षण थोड़ा आसान हो सकता है, लेकिन यह ज़्यादातर काम कर देता है।
  • एक काम करने वाला GPU प्रोफाइलर जो प्रति-पास प्रदर्शन आँकड़े (समय, बैंडविड्थ) और प्रति-शेडर निष्पादन समय भी दिखाता है। चूँकि GPU एक टाइलर है, आप निश्चित रूप से प्रति-ड्रॉ-कॉल टाइमिंग की उम्मीद नहीं कर सकते। इस स्तर की दृश्यता होना - खासकर iOS पर ग्राफिक्स API में किसी भी GPU टाइमिंग जानकारी की पूरी कमी को देखते हुए - बहुत बढ़िया है।
  • एक काम करने वाला CPU/GPU टाइमलाइन ट्रेस (मेटल सिस्टम ट्रेस) जो CPU और GPU रेंडरिंग वर्कलोड की शेड्यूलिंग दिखाता है, GPUView के समान है लेकिन कुछ UI विचित्रताओं को छोड़कर, वास्तव में उपयोग में आसान है।
  • एक ऑफ़लाइन शेडर कंपाइलर जो आपके शेडर सिंटैक्स को मान्य करता है, कभी-कभी आपको उपयोगी चेतावनियाँ देता है, आपके शेडर को एक बाइनरी ब्लॉब में परिवर्तित करता है जिसे रनटाइम पर लोड करना काफी तेज़ होता है और साथ ही पहले से ही उचित रूप से अनुकूलित होता है, जिससे लोड समय कम हो जाता है क्योंकि ड्राइवर कंपाइलर तेज़ हो सकता है।

यदि आप Direct3D या कंसोल की दुनिया से आते हैं, तो आप इनमें से हर एक चीज़ को सामान्य मान सकते हैं - मुझ पर विश्वास करें, OpenGL में इनमें से हर एक चीज़ असामान्य है और इसे उत्साह से देखा जाता है, खासकर मोबाइल पर जहाँ आप कभी-कभी खराब ड्राइवरों, बिना किसी सत्यापन, बिना किसी GPU डिबगर, बिना किसी मददगार GPU प्रोफाइलर, GPU शेड्यूलिंग डेटा इकट्ठा करने की क्षमता के बिना काम करने और एक टेक्स्ट-आधारित शेडर भाषा के साथ काम करने के लिए मजबूर हैं, जिसके लिए प्रत्येक विक्रेता का पार्सर थोड़ा अलग होता है।

मेटल कोड लिखने और एप्लिकेशन शिप करने, दोनों के लिए एक बेहतरीन API है। इसका उपयोग करना आसान है, इसकी प्रदर्शन क्षमता अनुमानित है, इसके ड्राइवर मजबूत हैं और टूलसेट ठोस है। यह पोर्टेबिलिटी को छोड़कर हर एक पहलू में ओपनजीएल से बेहतर है, लेकिन ओपनजीएल के साथ वास्तविकता यह है कि आपको वास्तव में इसका उपयोग केवल तीन प्लेटफार्मों (iOS, Android और Mac) पर ही करना चाहिए था, और उनमें से दो अब मेटल का समर्थन करते हैं; इसके अतिरिक्त, ओपनजीएल का पोर्टेबिलिटी का वादा काफी हद तक पूरा नहीं हुआ है क्योंकि आप जिस प्लेटफॉर्म पर कोड लिखते हैं, वह बहुत बार अलग-अलग कारणों से दूसरे प्लेटफॉर्म पर काम नहीं करता है।

यदि आप यूनिटी या UE4 जैसे किसी थर्ड-पार्टी इंजन का उपयोग कर रहे हैं, तो मेटल पहले से ही वहाँ समर्थित है; यदि आप ऐसा नहीं कर रहे हैं और आपको ग्राफिक्स प्रोग्रामिंग पसंद है या आप प्रदर्शन को लेकर बहुत गंभीर हैं और iOS या Mac को गंभीरता से लेते हैं, तो मैं आपको पुरजोर सलाह देता हूँ कि आप मेटल को आज़माएँ। आप निराश नहीं होंगे।

मेटल नाउ

पिछले तीन वर्षों में हमारी दृष्टि से मेटल में जो सबसे बड़े बदलाव आए हैं, वे बड़े पैमाने पर इसके अपनाए जाने को लेकर हैं।

तीन साल पहले, एक चौथाई डिवाइस को OpenGL का उपयोग करना पड़ता था। आज, हमारे दर्शकों के लिए, यह संख्या ~2% है - जिसका मतलब है कि हमारा OpenGL बैकएंड अब लगभग मायने नहीं रखता। हम अभी भी इसे बनाए रखते हैं लेकिन यह लंबे समय तक नहीं चलेगा।

ड्राइवर भी पहले से कहीं बेहतर हैं - सामान्य तौर पर, हमें iOS पर ड्राइवर संबंधी समस्याएं नहीं दिखती हैं, और जब दिखती भी हैं तो वे अक्सर शुरुआती प्रोटोटाइप पर होती हैं, और जब तक प्रोटोटाइप उत्पादन में आते हैं, तब तक समस्याएं आमतौर पर ठीक हो जाती हैं।

हमने अपने मेटल बैकएंड को बेहतर बनाने में भी कुछ समय बिताया है, तीन क्षेत्रों पर ध्यान केंद्रित करते हुए:

शेडर कंपाइलेशन टूलचेन का पुनर्निर्माण

पिछले तीन वर्षों में एक और महत्वपूर्ण घटना वल्कन का रिलीज़ और विकास है। हालांकि ऐसा लगता है कि एपीआई पूरी तरह से अलग हैं (और वे हैं भी), वल्कन इकोसिस्टम ने रेंडरिंग समुदाय को ओपन-सोर्स टूल्स का एक शानदार सेट दिया है, जो मिलकर एक उपयोग में आसान, प्रोडक्शन-क्वालिटी कंपाइलेशन टूलसेट बनाते हैं।

हमने इन लाइब्रेरियों का उपयोग एक कंपाइलेशन टूलचेन बनाने के लिए किया जो HLSL सोर्स कोड (विभिन्न DX11 सुविधाओं का उपयोग करते हुए, जिसमें कंप्यूट शेडर्स शामिल हैं) ले सकता है, इसे SPIRV में कंपाइल कर सकता है, उक्त SPIRV का अनुकूलन कर सकता है, और परिणामी SPIRV को MSL (मेटल शेडिंग लैंग्वेज) में परिवर्तित कर सकता है। यह हमारे पिछले टूलचेन की जगह लेता है जो केवल DX9 HLSL सोर्स को इनपुट के रूप में उपयोग कर सकता था और जटिल शेडर्स के लिए इसमें विभिन्न शुद्धता संबंधी समस्याएं थीं।

यह कुछ हद तक विडंबना है कि एप्पल का इससे कोई लेना-देना नहीं था, लेकिन हम यहाँ हैं। glslang (https://github.com/KhronosGroup/glslang), spirv-opt (https://github.com/KhronosGroup/SPIRV-Tools) और SPIRV-Cross (https://github.com/KhronosGroup/SPIRV-Cross) के योगदानकर्ताओं और रखरखावकर्ताओं का बहुत-बहुत धन्यवाद। हमने इन लाइब्रेरियों में पैच का एक सेट भी योगदान दिया है ताकि हम नया टूलचेन भी शिप कर सकें, और इसका उपयोग हमारे शेडर्स को Vulkan, Metal और OpenGL APIs पर रीटारगेट करने के लिए कर सकें।

macOS समर्थन

macOS पोर्ट हमेशा एक संभावना थी, लेकिन जब तक हमें कुछ सुविधाओं की कमी महसूस नहीं हुई, तब तक यह हमारे लिए कोई बड़ा फोकस नहीं था। इसलिए हमने फैसला किया कि हमें तेज़ रेंडरिंग प्राप्त करने और भविष्य के लिए कुछ संभावनाओं को खोलने के लिए macOS पर Metal में निवेश करना चाहिए।

अमलीकरण के दृष्टिकोण से, यह बिल्कुल भी बहुत कठिन नहीं था। अधिकांश एपीआई बिल्कुल समान है; विंडो प्रबंधन के अलावा, एकमात्र क्षेत्र जिसमें पर्याप्त बदलाव की आवश्यकता थी, वह मेमोरी आवंटन था। मोबाइल पर, बफ़र्स और टेक्सचर्स के लिए एक साझा मेमोरी स्पेस होता है जबकि डेस्कटॉप पर, एपीआई एक समर्पित जीपीयू को मानता है जिसकी अपनी वीडियो मेमोरी होती है।

प्रबंधित संसाधनों (managed resources) का उपयोग करके इसे जल्दी से काम चलाने का एक तरीका है, जहाँ मेटल रनटाइम आपके लिए डेटा की प्रतिलिपि बनाने का काम करता है। हमने अपना पहला संस्करण इसी तरह से जारी किया था, लेकिन बाद में हमने स्क्रैच बफ़र्स (scratch buffers) का उपयोग करके संसाधन डेटा को अधिक स्पष्ट रूप से कॉपी करने के लिए कार्यान्वयन पर फिर से काम किया, ताकि हम सिस्टम मेमोरी के ओवरहेड को कम कर सकें।

macOS और iOS के बीच सबसे बड़ा अंतर स्थिरता का था। iOS पर हम एक आर्किटेक्चर पर सिर्फ एक ड्राइवर विक्रेता के साथ काम कर रहे थे, जबकि macOS पर हमें सभी तीन विक्रेताओं (इंटेल, एएमडी, एनवीडिया) का समर्थन करना था। इसके अतिरिक्त, iOS पर हमने - सौभाग्य से! - iOS का *पहला* संस्करण, जिसमें मेटल उपलब्ध था, यानी iOS 8, को छोड़ दिया था, और macOS पर यह व्यावहारिक नहीं था क्योंकि उस समय मेटल का उपयोग करने वाले हमें बहुत कम उपयोगकर्ता मिलते। इन समस्याओं के संयोजन के कारण, हमें macOS पर API के अपेक्षाकृत हानिरहित और अपेक्षाकृत अस्पष्ट दोनों क्षेत्रों में कई और ड्राइवर संबंधी समस्याओं का सामना करना पड़ा है।

हम अभी भी macOS Metal के सभी संस्करणों (10.11+) का समर्थन करते हैं, हालांकि हमने कुछ ऐसे संस्करणों के लिए समर्थन हटाना और लेगेसी OpenGL बैकएंड पर स्विच करना शुरू कर दिया है, जिनमें शेडर कंपाइलर बग्स ज्ञात हैं, जिनसे निपटना हमारे लिए मुश्किल है, उदाहरण के लिए, 10.11 पर Metal को चलाने के लिए अब हमें macOS 10.11.6 की आवश्यकता है।

प्रदर्शन के लाभ हमारी अपेक्षाओं के अनुरूप थे; बाज़ार हिस्सेदारी के मामले में, आज हम macOS प्लेटफ़ॉर्म पर ~25% OpenGL और ~75% Metal उपयोगकर्ताओं पर हैं, जो एक बहुत ही स्वस्थ विभाजन है। इसका मतलब है कि भविष्य में किसी समय हमारे लिए डेस्कटॉप OpenGL का समर्थन पूरी तरह से बंद करना व्यावहारिक हो सकता है, क्योंकि हमारे द्वारा समर्थित कोई अन्य प्लेटफ़ॉर्म इसका उपयोग नहीं करता है, जो उन एपीआई पर ध्यान केंद्रित करने के मामले में बहुत अच्छा है जिनका समर्थन करना आसान है और जिनसे अच्छा प्रदर्शन मिलता है।

प्रदर्शन और मेमोरी खपत पर पुनरावृत्ति

हम ऐतिहासिक रूप से उन ग्राफिक्स एपीआई सुविधाओं के मामले में काफी रूढ़िवादी रहे हैं जिनका हम उपयोग करते हैं, और मेटल भी इसका अपवाद नहीं है। पिछले कुछ वर्षों में मेटल में कई बड़ी सुविधाएँ जोड़ी गई हैं, जिनमें एक्सप्लिसिट हीप्स के साथ बेहतर संसाधन आवंटन एपीआई, मेटल 2 के साथ टाइल शेडर्स, आर्गुमेंट बफ़र्स और जीपीयू-साइड कमांड जनरेशन आदि शामिल हैं।

हम ज़्यादातर नई सुविधाओं का उपयोग नहीं करते हैं। अब तक, प्रदर्शन ठीक रहा है, और हम उन सुधारों पर ध्यान केंद्रित करना चाहेंगे जो हर जगह लागू हों, इसलिए टाइल शेडर्स जैसी कोई चीज़, जिसके लिए हमें पूरे रेंडरर में इसके लिए बहुत खास सपोर्ट लागू करना होगा और जो केवल नए हार्डवेयर पर ही उपलब्ध है, कम दिलचस्प है।

इसके बावजूद, हम बैकएंड के विभिन्न हिस्सों को सिर्फ *तेज़ी से* चलाने के लिए कुछ समय खर्च करते हैं - जैसे कि लेवल लोड के दौरान रुक-रुक कर चलने की समस्या को कम करने के लिए पूरी तरह से असिंक्रोनस टेक्सचर अपलोड का उपयोग करना, जो बिल्कुल आसान था, macOS पर उपरोक्त मेमोरी ऑप्टिमाइज़ेशन करना, कैश मिस को कम करके बैकएंड के विभिन्न हिस्सों में CPU डिस्पैच को अनुकूलित करना आदि, और - उन कुछ नई सुविधाओं में से एक जिसके लिए हमारे पास स्पष्ट समर्थन है - जब भी उपलब्ध हो मेमोरीलेस टेक्सचर स्टोरेज का उपयोग करना, ताकि हमारे नए शैडो सिस्टम के लिए आवश्यक मेमोरी को काफी कम किया जा सके।

भविष्य

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

हम लगातार विभिन्न एपीआई के लिए किए जाने वाले काम की मात्रा के बीच संतुलन का पुनर्मूल्यांकन करते रहते हैं - बहुत संभावना है कि हमें भविष्य की कुछ रेंडरिंग परियोजनाओं के लिए मेटल एपीआई के अधिक आधुनिक हिस्सों में और गहराई तक जाना होगा; यदि ऐसा होता है, तो हम इस बारे में एक और पोस्ट लिखना सुनिश्चित करेंगे!

  1. हाँ, ठीक है, और शायद परीक्षण के दौरान पाए गए कुछ बग्स को ठीक करने में एक सप्ताह
  2. ये नंबर A10 पर प्रति फ्रेम अपडेट किए गए 128 KB डेटा (दो 32x16x32 RGBA8 क्षेत्र) के हैं

न तो Roblox कॉर्पोरेशन और न ही यह ब्लॉग किसी भी कंपनी या सेवा का समर्थन या अनुमोदन करता है। साथ ही, इस ब्लॉग में निहित जानकारी की सटीकता, विश्वसनीयता या पूर्णता के संबंध में कोई गारंटी या वादा नहीं किया जाता है।

यह ब्लॉग पोस्ट मूल रूप से Roblox Tech Blog पर प्रकाशित हुई थी।