आधुनिक खेलों में डबल या ट्रिपल बफरिंग से क्या समस्या आती है?


31

मैं जांचना चाहता हूं कि क्या डबल (या ट्रिपल) बफरिंग का उपयोग करने के कारणों के बारे में मेरी समझ सही है:

60 हर्ट्ज रिफ्रेश के साथ एक मॉनीटर-डिस्प्ले 60 सेकंड प्रति सेकंड। यदि मॉनिटर मॉनिटर-डिस्प्ले को रिफ्रेश करता है, तो वह पिक्सेल को पिक्सेल के लिए और लाइन के लिए लाइन को अपडेट करता है। मॉनिटर वीडियो मेमोरी से पिक्सेल के लिए रंग मानों का अनुरोध करता है।

अगर मैं अब एक गेम चलाता हूं, तो यह गेम लगातार इस वीडियो मेमोरी में हेरफेर कर रहा है।

यदि यह गेम बफर रणनीति (डबल बफरिंग आदि) का उपयोग नहीं करता है, तो निम्न समस्या हो सकती है:

मॉनिटर अब उसके मॉनिटर-डिस्प्ले को रिफ्रेश कर रहा है। इस समय मॉनीटर ने पहले हाफ मॉनीटर-डिस्प्ले को पहले ही रिफ्रेश कर दिया था। इसी समय, गेम ने नए डेटा के साथ वीडियो मेमोरी में हेरफेर किया था। अब मॉनीटर दूसरे हाफ मॉनीटर-डिस्प्ले के लिए इस नए हेरफेर किए गए डेटा को वीडियो मेमोरी से एक्सेस करता है। समस्याएं आंसू या झिलमिलाहट हो सकती हैं।

क्या बफर रणनीति का उपयोग करने के मामलों के बारे में मेरी समझ सही है? क्या अन्य कारण हैं?

जवाबों:


62

मूल रूप से, प्रतिपादन में एक मूल लक्ष्य एक एकल, सुसंगत छवि पेश करने के लिए मॉनिटर पर प्रदर्शित प्रत्येक फ्रेम के लिए है। कई अलग-अलग रणनीतियाँ हैं जो इसे प्राप्त करने के लिए उपयोग की जाती हैं, या थीं।

निम्नलिखित में, मैं "vsync" का उल्लेख करता हूं। Vsync वह क्षण है जिस पर मॉनिटर एक नई स्क्रीन छवि बनाना शुरू करता है; यह वह बिंदु है जिस पर "vblank" एक पारंपरिक CRT स्क्रीन पर शुरू होता है, जहां स्कैनलाइन पल-पल की ड्राइंग को रोकती है और मॉनिटर के शीर्ष पर वापस चली जाती है। यह पल फ्रेम के कई दृष्टिकोणों के लिए बहुत महत्वपूर्ण है।

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

शून्य बफर

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

एकल बफर

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

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

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

ध्यान दें कि आधुनिक ऑपरेटिंग सिस्टम में, आपके पास आमतौर पर एकल-बफ़र खींचने का अवसर नहीं होता है, हालांकि यह तीस साल पहले काफी आम था। (गोश मैं अभी बूढ़ा महसूस करता हूँ - यह वही है जो मैं तब कर रहा था जब मैंने पहली बार खेल विकास में शुरुआत की थी)

डबल-बफर

यह पहले की गई रणनीतियों की तुलना में बहुत सरल है।

एक डबल-बफ़रिंग सिस्टम में, हमारे पास दो अलग-अलग स्क्रीन छवियों को संग्रहीत करने के लिए पर्याप्त मेमोरी है, और इसलिए हम उनमें से एक को "फ्रंट बफर" और दूसरे को "बैक बफर" के रूप में नामित करते हैं। "फ्रंट बफर" वह है जो वर्तमान में प्रदर्शित किया जा रहा है, और "बैक बफर" वह जगह है जहां हम वर्तमान में ड्राइंग कर रहे हैं।

जब हम बैक बफर में एक स्क्रीन की छवि बनाना समाप्त करते हैं, तो हम vsync तक प्रतीक्षा करते हैं, और फिर दो बफ़र्स स्वैप करते हैं। इस तरह, बैक बफर फ्रंट बफर बन जाता है, और इसके विपरीत, और पूरी स्वैप तब हुआ जब मॉनिटर कुछ भी ड्राइंग नहीं कर रहा था।

ट्रिपल-बफर

डबल-बफर एप्रोच के साथ अक्सर उठाया जाने वाला एक मुद्दा यह है कि जब हम बैक बफर के लिए ड्राइंग खत्म कर लेते हैं, तो हमें बफ़र्स को स्वैप करने और काम करना जारी रखने से पहले बस vsync की प्रतीक्षा में बैठना पड़ता है; हम उस समय के दौरान गणना कर सकते थे! क्या अधिक है, हर समय हम बफ़र्स के बीच स्वैप करने के लिए इंतजार कर रहे हैं, उस बैक बफर में छवि पुरानी और पुरानी हो रही है, इस प्रकार उपयोगकर्ता की कथित विलंबता बढ़ रही है।

ट्रिपल-बफर सिस्टम में, हम खुद को तीन बफ़र बनाते हैं - एक फ्रंट बफ़र और दो बैक बफ़र। विचार यह है:

मॉनिटर सामने बफर प्रदर्शित कर रहा है, और हम बैक बफर # 1 में आ रहे हैं। यदि हम मॉनिटर को सामने वाले बफर को खींचने से पहले बैक बफर # 1 में ड्राइंग खत्म करते हैं, तो हम vsync की प्रतीक्षा करने के बजाय, हम तुरंत अगले फ्रेम को बैक बफर # 2 में चित्रित करना शुरू करते हैं। यदि हम समाप्त कर देते हैं और vsync अभी भी नहीं आए हैं, तो हम वापस # 1 बफर में ड्राइंग शुरू करते हैं, और इसी तरह। विचार यह है कि जब vsync अंततः होता है, तो हमारे बैक बफ़र्स में से एक या दूसरा पूरा हो जाएगा, और सामने वाले बफर के लिए एक स्वैप किया जा सकता है।

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

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

GPU विक्रेता वर्तमान में सलाह देते हैं कि आप अपने आप को ट्रिपल-बफरिंग लागू नहीं करते हैं - ड्राइवर आपके लिए यह स्वचालित रूप से करेगा।


7
यह एक अविश्वसनीय रूप से विस्तृत उत्तर है, और यह बताता है कि बहुत सारी चीजों को जिस तरह से किया जाता है (जैसे स्क्रीन समन्वय स्थान, आदि)। इसके अलावा मेरे सवाल का जवाब दिया "क्यों चौगुनी नहीं बफ़र्स? क्विंटुपल?" मुझे एहसास नहीं हुआ कि बैकग्राउंड स्वैपिंग बैकग्राउंड में हुई है, जिसका अर्थ है कि दो बैक बफ़र्स की अधिकतम आवश्यकता है। Upvoted।
लंचमीट 317

असल में इसमें क्वाड बफरिंग मौजूद है। यह त्रिविम दृश्य के लिए दोहरी बफ़रिंग है। स्विफ्टलेस.com
Narek

@Narek No. आपके लिंक से उद्धृत: "आप वास्तव में कंप्यूटर ग्राफिक्स वातावरण में वास्तविक क्वाड बफरिंग को सक्षम नहीं कर सकते क्योंकि कोई वास्तविक बिंदु नहीं है"। यह सुझाव देना कि एक साथ दो अलग-अलग विचारों पर डबल बफ़र करना "क्वाड बफ़रिंग" होगा, केवल वर्डप्ले को मनोरंजक बना रहा है; कुछ असली नहीं।
ट्रेवर पॉवेल

@TrevorPowell आप जिस हिस्से को शामिल करना भूल गए थे, उसमें शामिल हैं: "ठीक है, आम तौर पर क्वाड बफरिंग एक स्टीरियोस्कोपिक वातावरण में डबल बफरिंग को संदर्भित करता है। उदाहरण के लिए: आपके पास दो डिस्प्ले हैं, आमतौर पर 3 डी उद्देश्यों के लिए और प्रत्येक आंख डबल बफर है।" अब संदर्भ अधिक स्पष्ट हो सकता है।
नारेक

@TrevorPowell आपकी बात हालांकि पूरी तरह से स्पष्ट है। यह समझ में नहीं आता कि एक रेंडर बफर के लिए 3 से अधिक बफ़र्स हैं।
नारेक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.