गेम लूप और ओपनजीएल के बीच मल्टीथ्रेडिंग का लाभ उठाते हुए


10

OpenGL रेंडर पर आधारित गेम के संदर्भ में बात करना:

मान लेते हैं कि दो सूत्र हैं:

  1. खेल की वस्तुओं के लिए खेल तर्क और भौतिकी आदि को अद्यतन करता है

  2. गेम ऑब्जेक्ट्स में डेटा के आधार पर प्रत्येक गेम ऑब्जेक्ट के लिए ओपनल ड्रॉ कॉल करता है (वह थ्रेड 1 अपडेट करता रहता है)

जब तक आपके पास खेल की वर्तमान स्थिति में प्रत्येक गेम ऑब्जेक्ट की दो प्रतियां हैं, तो आपको थ्रेड 1 को रोकना होगा जबकि थ्रेड 2 ड्रॉ कॉल करता है अन्यथा गेम ऑब्जेक्ट उस ऑब्जेक्ट के लिए ड्रॉ कॉल के बीच में अपडेट हो जाएगा, जो अवांछनीय है!

लेकिन थ्रेड 2 से सुरक्षित रूप से ड्रॉ कॉल करने के लिए थ्रेड 1 को रोकना मल्टीथ्रेडिंग / कंसीडर के पूरे उद्देश्य को मारता है

क्या सैकड़ों या हजारों या सिंक ऑब्जेक्ट्स / बाड़ का उपयोग करने के अलावा इसके लिए एक बेहतर दृष्टिकोण है ताकि प्रदर्शन के लिए मल्टीकोर वास्तुकला का फायदा उठाया जा सके?

मुझे पता है कि मैं अभी भी उन वस्तुओं के लिए बनावट और संकलन शेड के लिए मल्टीथ्रेडिंग का उपयोग कर सकता हूं जो वर्तमान गेम स्थिति का हिस्सा होना बाकी है, लेकिन मैं ड्रॉ और अपडेट के साथ संघर्ष किए बिना सक्रिय / दृश्यमान वस्तुओं के लिए कैसे करूं?

क्या होगा अगर मैं गेम ऑब्जेक्ट में से प्रत्येक में अलग सिंक लॉक का उपयोग करता हूं? इस तरह से कोई भी धागा पूरे अद्यतन / ड्रा चक्र के बजाय केवल एक ऑब्जेक्ट (आदर्श मामले) पर ब्लॉक करेगा! लेकिन प्रत्येक वस्तु पर कितना महंगा ताले लग रहे हैं (खेल में एक हजार वस्तुएं हो सकती हैं)?


1. यह मानते हुए कि सिर्फ दो धागे ही अच्छे नहीं होंगे, 4 कोर बहुत आम हैं और केवल बढ़ेंगे। 2. बेस्ट प्रैक्टिस स्ट्रेटेजी जवाब: कमांड क्वेरी रिस्पांसिबिलिटी सेग्रीगेशन एंड एक्टर मॉडल / कंपोनेंट एंटिटी सिस्टम लागू करें। 3. यथार्थवादी जवाब: बस इसे ताले और सामान के साथ पारंपरिक सी ++ तरीका हैक करें।
डेन

एक आम डेटास्टोर, एक लॉक।
जस्टिन

@ अन्याय जैसा कि मैंने एक सिंक लॉक के साथ कहा था कि मल्टीथ्रेडिंग का एकमात्र लाभ दिन के उजाले में क्रूरतापूर्वक हत्या कर दिया जाएगा, अपडेट थ्रेड को तब तक इंतजार करना होगा जब तक ड्रॉ थ्रेड सभी ऑब्जेक्ट्स के लिए कॉल नहीं करेगा, ड्रॉ थ्रेड तब तक इंतजार करेगा जब तक कि अपडेट लूप सामान पूरा नहीं कर लेता। ! जो सिंगल थ्रेडेड दृष्टिकोण से भी बदतर है
अल्जाने

1
ऐसा लगता है कि async ग्राफिक्स एपीआई (जैसे ओपनजीएल) के साथ गेम्स में मल्टीथ्रेडेड दृष्टिकोण अभी भी सक्रिय विषय है और कोई मानक या सही समाधान के पास नहीं है
अल्जाने

1
आपके इंजन और आपके रेंडरर के लिए जो डेटास्टोर सामान्य है, वह आपका गेम ऑब्जेक्ट नहीं होना चाहिए। यह कुछ प्रतिनिधित्व होना चाहिए कि रेंडरर जितनी जल्दी संभव हो सके।
जस्टिन

जवाबों:


13

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

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

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

अंत में, मैं पढ़ने की सलाह देता हूं:


बस उत्सुक! आप कैसे जानते हैं कि डूम 3 ने इस दृष्टिकोण का उपयोग किया है? मैंने सोचा था कि डेवलपर्स ने कभी भी तकनीकों को बाहर नहीं जाने दिया!
अल्लाहजाने

4
@ आलजाने, कयामत 3 ओपन सोर्स है । मेरे द्वारा प्रदान किए गए लिंक में, आपको गेम की समग्र वास्तुकला की समीक्षा मिलेगी। और आप गलत हैं, हाँ पूरी तरह से ओपन सोर्स गेम्स मिलना दुर्लभ है, लेकिन डेवलपर्स आमतौर पर ब्लॉग, कागजात और घटनाओं जैसे जीडीसी में अपनी तकनीकों और चालों को उजागर करते हैं ।
Glampert

1
हम्म। यह एक भयानक पढ़ा था! मुझे इससे अवगत कराने के लिए धन्यवाद! आप टिक जाते हैं :)
अल्लाहजैन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.