OpenGL को स्क्रीन को वास्तव में अपडेट करने में कितना समय लगता है?


9

मेरे पास सी में एक सरल ओपनगैल टेस्ट ऐप है जो कुंजी इनपुट के जवाब में विभिन्न चीजों को आकर्षित करता है। (मेसा 8.0.4, मेसा-ईजीएल के साथ और GLFW, Ubuntu 12.04LTS के साथ एक पीसी पर NVIDIA GT4650 के साथ प्रयास किया गया)। ड्रॉ काफी सरल / तेज (सामान के त्रिकोण प्रकार घूमना) हैं। मेरा परीक्षण कोड किसी भी तरह से जानबूझकर सीमा को सीमित नहीं करता है, यह सिर्फ इस तरह दिखता है:

while (true)
{
    draw();
    swap_buffers();
}

मैंने यह बहुत सावधानी से तय किया है, और मुझे पता है कि एक eglSwapBuffers()(या glfwSwapBuffers, एक ही चीज़) से अगली कॉल का समय ~ 16.6 मिलीसेकंड है। eglSwapBuffers()अगली कॉल से ठीक पहले कॉल करने के बाद का समय इससे थोड़ा ही कम है, फिर भी जो खींचा गया है वह बहुत सरल है। स्वैप बफ़र्स कॉल करने का समय 1ms से कम है।

हालाँकि, ऐप से जो समय बदल रहा है वह कुंजी प्रेस के जवाब में आ रहा है जो वास्तव में स्क्रीन पर दिखाई दे रहा बदलाव है>> 150ms (लगभग 8-9 फ्रेम लायक) है। इसे स्क्रीन के कैमरा रिकॉर्डिंग और 60fps पर कीबोर्ड से मापा जाता है।

इसलिए, प्रश्न:

  1. बफ़र्स को स्वैप करने और वास्तव में स्क्रीन पर दिखाने के लिए कॉल के बीच बफ़र कहाँ हैं? देरी क्यों? यह निश्चित रूप से लगता है कि ऐप हर समय स्क्रीन के आगे कई फ्रेम खींच रहा है।

  2. एक OpenGL एप्लिकेशन स्क्रीन पर तत्काल आकर्षित करने के लिए क्या कर सकता है? (यानी: कोई बफरिंग नहीं है, बस तब तक ब्लॉक करें जब तक ड्रा पूरा न हो; मुझे उच्च थ्रूपुट की आवश्यकता नहीं है, मुझे कम विलंबता की आवश्यकता है)

  3. उपर्युक्त तात्कालिक ड्रॉ को जितनी जल्दी हो सके करने के लिए एक आवेदन क्या कर सकता है?

  4. किसी एप्लिकेशन को कैसे पता चल सकता है कि वास्तव में अभी स्क्रीन पर क्या है? (या, वर्तमान बफ़रिंग देरी कितने फ्रेम / कितने समय के लिए है?)


क्या आप उस समय को अलग कर सकते हैं जो कीबोर्ड आपके एप्लिकेशन को उस समय को सूचित करने के लिए लेता है जो वास्तव में उसे प्रस्तुत करता है?
थोरिनी

@ थोरिनि: फेयर पॉइंट। मैं संभवत: एक समानांतर पोर्ट आदि पर एलईडी का उपयोग करके कुछ हैक करने का संकेत दे सकता हूं जब एप्लिकेशन वास्तव में कुंजी प्रेस प्राप्त करता है। फिर भी, यह सिर्फ fgetc (स्टडिन) है, यह कितना धीमा हो सकता है? : /
एलेक्स I

मैं इस धारणा के तहत था कि glFlush का उपयोग सभी कमांड के तत्काल फ्लश का कारण बनता है।
प्रोग्राममेउड

1
जाँच @AlexI इस gamedev.stackexchange.com/questions/66543/... आप मदद कर सकता है
concept3d

1
@ concept3d: हाँ, यह मूल रूप से उत्तर दिया गया है, बस सोचा था कि आप कुछ अतिरिक्त प्रतिनिधि चाहेंगे :) जाहिर है मुझे इसे पुरस्कृत करने के लिए एक दिन इंतजार करना होगा।
एलेक्स I

जवाबों:


6

सीपीयू से बुलाए गए किसी भी ड्राइंग एपीआई फ़ंक्शन को जीपीयू कमांड रिंग बफर को बाद में जीपीयू द्वारा निष्पादित किया जाएगा। इसका मतलब यह है कि OpenGL फ़ंक्शन ज्यादातर गैर-अवरुद्ध कार्य हैं। इसलिए CPU और GPU समानांतर में काम करेंगे।

ध्यान देने वाली सबसे महत्वपूर्ण बात यह है कि आपका एप्लिकेशन सीपीयू या जीपीयू बाध्य हो सकता है। एक बार जब आप glFinish को कॉल करते हैं तो CPU को प्रतीक्षा करना चाहिए कि वह ड्रॉइंग कमांड को पूरा करने के लिए, यदि GPU अधिक समय ले रहा है और CPU को स्टाल कर सकता है / कर रहा है तो आपके एप्लिकेशन GPU बाध्य हैं। यदि GPU इसे आरेखित कमांडों को पूरा करता है और CPU glFinish में बहुत लंबा समय ले रहा है तो आपका एप्लिकेशन CPU बाध्य है।

और ध्यान दें कि glFlushऔर के बीच अंतर है glFinish

glFlush: इंगित करता है कि पहले से जीएल को भेजे गए सभी आदेशों को परिमित समय में पूरा करना होगा।

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

glXSwapBuffers लौटने से पहले एक अंतर्निहित glFlush करता है। इसके बाद OpenGL कमांड glXSwapBuffers को कॉल करने के तुरंत बाद जारी किया जा सकता है, लेकिन बफर एक्सचेंज पूरा होने तक निष्पादित नहीं किया जाता है।

वास्तविक फ़्रेम समय सबसे अधिक संभावना है कि दो सीपीयू / जीपीयू में से किसको अपना काम पूरा करने में अधिक समय लगता है।


यह बहुत मददगार है। कुछ संभावित सुधार: opengl.org/sdk/docs/man2/xhtml/glXSwapBuffers.xml "glXSwapBuffers एक निहित glFlush करता है, इससे पहले कि वह" यह वास्तव में एक glFinish नहीं करता है, ऐसा लगता है, इसलिए कमांड बफ़र काफी हो सकता है इसमें सामान तब आता है जब स्वैप बफ़र वापस आता है।
एलेक्स I

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

both low framerate (exactly same as monitor refresh rate??जब तक आप स्पष्ट रूप से VSync का उपयोग नहीं कर रहे हैं, तब तक @AlexI नहीं।
कांसेप्ट 3 डी

@AlexI मैं यह भी बताना चाहता हूं कि फ्रेम समय एफपीएस से अलग है, अपने आवेदन को प्रोफाइल करने के लिए फ्रेम समय का उपयोग करें क्योंकि यह रैखिक है। दूसरी ओर एफपीएस एक खराब माप है जो रैखिक नहीं है।
अवधारणा ३ डी

मैं स्पष्ट रूप से vsync का उपयोग नहीं कर रहा हूँ। मैं डिफॉल्स vsync सेटिंग्स को बदलने के लिए कुछ नहीं कर रहा हूं, मुझे यह भी नहीं पता है कि ओपनजीएल में उन लोगों को कहां बदलना है। मुझे बस 60fps (एक प्रतिशत के भीतर) मिलता है।
एलेक्स I

4

OpenGL स्क्रीन को कभी भी तकनीकी रूप से अपडेट नहीं करता है।

एक विंडो सिस्टम एपीआई है जो GL (जैसे GLX, WGL, CGL, EGL) से अलग है जो ऐसा करता है। बफर इन एपीआई का उपयोग करते हुए आम तौर पर स्पष्ट रूप से आह्वान करते हैं, glFlush (...)लेकिन कुछ कार्यान्वयन में (उदाहरण के लिए विंडोज पर जीडीआई रेखापुंजक) यह एक पूर्ण करता है glFinish (...):

 

    * बाईं ओर, ICD (हार्डवेयर) पथ है SwapBuffers (...)। दाईं ओर, GDI (सॉफ़्टवेयर) पथ।

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

जब तक सभी बैक बफ़र्स समाप्त फ्रेम से भरे हुए हैं, तब तक उन्हें सामने की ओर ले जाया जाना है, स्वैप बफ़र्स को स्पष्ट रूप से अवरुद्ध करने का कारण होगा। अफसोस की बात है, ज्यादातर GL विंडो सिस्टम API ( 0 सिंगल-बफ़र्ड या 1 डबल-बफ़र्ड से अलग) द्वारा उपयोग किए गए बैक बफ़र्स की संख्या को स्पष्ट रूप से नियंत्रित करने का कोई तरीका नहीं है । ड्राइवर 2 बैक बफ़र्स का उपयोग करने के लिए स्वतंत्र है यदि वह चाहता है (ट्रिपल बफ़रिंग), लेकिन आप GLX या WGL जैसी किसी चीज़ का उपयोग करके आवेदन स्तर पर यह अनुरोध नहीं कर सकते।


Andon: अच्छी जानकारी, धन्यवाद। मुझे लगता है कि मैं जो देख रहा हूं वह आंशिक रूप से डबल बफरिंग है, लेकिन: "स्वैप से पहले बैक बफर को संशोधित करने का प्रयास ब्लॉक होना चाहिए" - क्यों? ऐसा लगता है कि सब कुछ कमांड बफर को भेजा जा सकता है, जिसमें स्वैप भी शामिल है :)
एलेक्स I

"स्पष्ट रूप से अधिकांश जीएल विंडो सिस्टम एपीआई (0 सिंगल-बफ़र्ड या 1 डबल-बफ़र्ड से अलग) द्वारा उपयोग किए गए बैक बफ़र्स की संख्या को नियंत्रित करें" - एकल / डबल बफ़र को कैसे नियंत्रित करता है?
एलेक्स I

@AlexI: मैंने भाषा को स्पष्ट किया है कि कमान को अवरुद्ध करने के लिए नेतृत्व क्यों किया जा सकता है। अन्य एपीआई में रेंडर-फॉरवर्ड नामक एक अवधारणा है, जो प्रभावी रूप से कमांड कतार की गहराई है। एकल / डबल बफ़र को नियंत्रित करने के लिए, जैसा कि आप अपने रेंडर संदर्भ बनाते समय आपके द्वारा चुने गए पिक्सेल प्रारूप द्वारा नियंत्रित होते हैं। WGL में, आप सिंगल या डबल-बफ़र का चयन कर सकते हैं, लेकिन यदि आप डबल-बफ़र का चयन करते हैं तो ड्राइवर वास्तव में 2 बैक बफ़र्स बना सकता है (इस प्रकार डबल बफ़रिंग ट्रिपल बफ़रिंग बन जाता है) यदि उपयोगकर्ता अपने ड्राइवर को ऐसा करने के लिए सेट करता है।
एंडन एम। कोलमैन

आप वास्तव में बहुत सारे फ़्रेमों को आगे नहीं करना चाहते क्योंकि यह ब्लॉकिंग को कम करेगा, यह विलंबता को भी बढ़ाता है। विलंबता को कम करने का सबसे अच्छा तरीका वास्तव में glFinish (...)बफ़र्स स्वैप करने के तुरंत बाद आह्वान करना है। यह कमांड कतार को साफ कर देगा, लेकिन इसका मतलब यह भी है कि GPU और CPU को सिंक्रनाइज़ किया जाएगा (जो कि यदि आप GPU को हर समय काम करना चाहते हैं तो अच्छा नहीं है)।
एंडन एम। कोलमैन

1

मुझे लगता है कि आप इस प्रयोग से परिचित हैं ?

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.