1. 程式人生 > >深度剖析OpenGL ES中的多執行緒和多視窗渲染技術

深度剖析OpenGL ES中的多執行緒和多視窗渲染技術

移動裝置中的CPU和GPU已經變得很強大,到處都是配備一個或多個高解析度螢幕的裝置,需要使用帶有圖形驅動器的複雜互動也日益增加。在這篇部落格文章中,我將討論多執行緒和多視窗渲染對開發人員來講意味著什麼,同時我將介紹將這些技術應用您設計當中的條件和時機。

什麼是多執行緒渲染?
傳統上,OpenGL ES應用程式只從一個執行緒渲染到一個圖層。然而,由於3D渲染引擎的複雜性有所增加,圖形API操作的CPU開銷已經成為瓶頸—尤其是載入資源時。這就使得多執行緒渲染引起關注。

渲染執行緒是與圖形環境關聯的CPU執行緒。預設情況下,每個圖形環境將無法訪問另一個環境中的資源(紋理、著色器和頂點緩衝區)。因此,需要使用共享環境,造成一個或多個後臺負載執行緒可訪問主執行緒的資源。這種渲染模式相當有效的原因有兩個:

1. 主執行緒不會阻塞
從根本上說,一直到應用程式和驅動程式記憶體之間的傳輸完成之前,上傳資料的圖形API呼叫一定會被阻塞。此外,在許多顯示卡驅動程式中著色器編譯就是阻塞型操作。這種阻塞造成開銷較大,導致GPU無法執行。將所有上傳操作遷移至後臺執行緒,主執行緒可以維持統一幀率

在多核CPU上進行並行任務分配
由於圖形驅動程式在CPU上執行,將這項執行分配至多個渲染執行緒,使得作業系統向多個CPU核心並行釋出指令。這就導致與單個渲染執行緒相比,驅動程式的工作負載能夠處理的更為迅速

使用多執行緒渲染?

1

2

OpenGL ES資料上傳—未經優化

OpenGL ES資料上傳—經優化

OpenGL ES資料上傳—未經優化


多執行緒渲染最適合於編譯著色器或上傳資料至顯示卡驅動器時CPU資源有限的應用程式。多執行緒渲染(完成之後效果明顯)能夠更好地分配驅動程式的任務,並使得應用程式保持統一幀率。

上述簡單示例當中,遊戲當中從一級升至二級需要上傳增加的紋理、 VBO和著色器程式。假設需要完成無縫升級(即啟動畫面、視訊等無法降低上傳開銷) ,仍在渲染一級時遊戲程式必須向驅動程式上傳新資源。

在未經優化的情況下,向驅動程式釋出呼叫指令時,由於增加了上傳/編譯操作負載,每幀所用時間並不一致。提交幀所增加的時間將會造成無法同步重新整理,幀率不一致,會感覺遊戲很卡。

經過優化的情況下,第二執行緒用於上傳資源。這就使得主執行緒維持統一的呼叫遞交時間,保證幀率一致。

最佳實踐
在實現最佳效能時,應在啟動程式時建立渲染執行緒。主執行緒應用於所有渲染。增加的執行緒(在共享環境中建立)應只用於著色器編譯和快取資料上傳。後臺執行緒的數量應保持在最低限度(如每個CPU核心一個執行緒) 。建立執行緒過多會導致難以維護,程式碼無法除錯。

呼叫eglMakeCurrent()應保持在最低限度以降低開銷(EGL specification規定在上下文一定要開啟新執行緒之前,必須重新整理所有未執行的操作)。

什麼情況下不應使用多執行緒渲染?
不受CPU資源限制或不涉及載入次數時
如果執行顯示卡驅動程式時,CPU資源足夠,就應該避免多執行緒渲染。它會增加渲染引擎的複雜性,如果處理得不好,甚至可能降低效能。

試圖“簡化”渲染引擎時
最糟的使用例項是不斷將單一圖形環境繫結至不同執行緒(使用eglmakeCurrent()) 。這樣很糟糕,原因有兩個:
The cost of context binding 上下文開銷
正如以上所述,呼叫eglMakeCurrent()迫使驅動程式取消所有未完成的操作

API calls are serialized API呼叫序列化
由於圖形環境在任何時點只能繫結到一個CPU執行緒,所有API呼叫將被序列提交

因此,API呼叫與單執行緒渲染的開銷一致(API呼叫提交呈序列化),但上行文轉換時需要額外開銷......也就是說與單執行緒渲染相比,效能會較差

似乎這是較好的設計,但以這種方式渲染會導致程式碼複雜凌亂,提交順序不清(甚至更難以除錯! ) 。
不要這樣做!

這是多視窗渲染?
多視窗渲染將一個應用程式渲染在多個視窗表面。通過作業系統視窗合成器(例如,Android系統的Surface Flinger或Linux發行版的X11)將這些視窗圖層進行合成,以提交至裝置螢幕。

在多視窗應用程式中,CPU執行緒和圖形環境呈一對一對映。每個圖形環境用於渲染到各自的視窗圖層。
什麼時候應該使用多視窗渲染?

多視窗渲染最適合用於應用程式需要渲染一個以上螢幕時,例如,當電視機作為第二屏時。
什麼時候不應該使用多視窗渲染?

合成層

3

多層合成—未經優化

4

多層合成—經優化

在上述未經優化的例項中,在單個圖層渲染遊戲場景、觸控控制元件和迷你地圖。應用程式利用作業系統合成器將這些圖層組合成可以顯示的圖層。由於必須要為多個圖層分配記憶體,因此這種方法較浪費資源,該合成器將處理未完全使用的透明畫素和GPU的隱藏面消除(HSR),(即被不透明UI元素覆蓋的片段冗餘著色) 。

在經優化的情況下,遊戲場景第一次渲染,然後觸控控制元件和迷你地圖直接渲染於同一圖層。在應用程式中FBO用於執行合成的情況下,這種方法並不適合。例如,遊戲場景可以被渲染至較低解析度FBO,將點陣圖傳輸至應用程式視窗表面,UI元素可以按原始解析度被驅動至頂點(這項技術通常用於在渲染遊戲場景時增加每個畫素的效能) 。

PVRTrace當中的多執行緒多視窗支援

自IMAGINATION釋出 PowerVR Graphics 3.2 SDK以來 ,PVRTrace(OpenGL ES捕獲和分析工具)支援需要執行這些複雜圖形驅動程式互動的應用程式。其中還包括Call View 和Frame Selector中的每執行緒狀態檢查器、每執行緒過濾,執行緒使用時間軸圖。所有這些功能組合使得多執行緒OpenGL ES更加便於除錯。此外,我們的 PVRVFrameOpenGL ES模擬器的多執行緒支援已經得到顯著改善。

自IMAGINATION釋出 PowerVR Graphics 3.2 SDK以來 ,PVRTrace(OpenGL ES捕獲和分析工具)支援需要執行這些複雜圖形驅動程式互動的應用程式。其中還包括Call View 和Frame Selector中的每執行緒狀態檢查器、每執行緒過濾,執行緒使用時間軸圖。所有這些功能組合使得多執行緒OpenGL ES更加便於除錯。此外,我們的 PVRVFrameOpenGL ES模擬器的多執行緒支援已經得到顯著改善。

相關推薦

深度剖析OpenGL ES執行視窗渲染技術

移動裝置中的CPU和GPU已經變得很強大,到處都是配備一個或多個高解析度螢幕的裝置,需要使用帶有圖形驅動器的複雜互動也日益增加。在這篇部落格文章中,我將討論多執行緒和多視窗渲染對開發人員來講意味著什麼,同時我將介紹將這些技術應用您設計當中的條件和時機。 什麼是多執行緒渲

OpenGL ES 執行渲染

“內容歸納” 應用程式和驅動程式之間的傳輸完成之前,阻塞型操作有: 1、上傳資料的圖形API呼叫; 2、顯示卡驅動程式中著色器編譯; 一、什麼情況下使用: 多執行緒渲染最適合於編譯著色器或上傳資料至顯示卡驅動器時CPU資源有限的應用程式。原因有2: 主執行緒

Python執行執行程序的效率對比實驗

Python是執行在直譯器中的語言,查詢資料知道,python中有一個全域性鎖(GIL),在使用多程序(Thread)的情況下,不能發揮多核的優勢。而使用多程序(Multiprocess),則可以發揮多核的優勢真正地提高效率。 對比實驗 資料顯示,如果多執行緒的程序是CPU密集型的,那多執行緒並不能有多少

Linux 執行程序的區別(小結)

最近學習Linux,看到“hairetz的專欄”的帖子不錯,特轉來大家一起學習。 很想寫點關於多程序和多執行緒的東西,我確實很愛他們。但是每每想動手寫點關於他們的東西,卻總是求全心理作祟,始終動不了手。 今天終於下了決心,寫點東西,以後可以再修修補補也無妨。一.為何需要多程序(或者多執行緒),為何需

搞定python執行程序

參考 https://www.cnblogs.com/whatisfantasy/p/6440585.html 1 概念梳理: 1.1 執行緒 1.1.1 什麼是執行緒 執行緒是作業系統能夠進行運算排程的最小單位。它被包含在程序之中,是程序中的實際運作單位。一條執行緒指的是程序中一個

python的執行程序

要使用Python的多執行緒,首先要了解一個概念。GIL(global interpreter lock),翻譯過來就是以直譯器為單位的全域性鎖。 用過執行緒鎖的都知道,LOCK就是用來管理住執行緒,讓一個指定的執行緒先執行,其他的先暫停(等待),避免執行緒的混亂,尤其是在共用變數的情況下。 GIL也是一

執行核下“鎖”的應用

  假設這樣一種情況:有多個執行緒(或多核)需要在共享資料A滿足某一條件時,對A進行操作. 以下舉例兩種實現 Fun_1() { lock()--------------1.1   Result=Check(A)-----1.2   Unlock()------------

【Linux】GDB除錯執行程序以及Core檔案

GDB偵錯程式 基本概念 GDB是GNU開源組織釋出的一個強大的UNIX下的程式除錯工具。或許,各位比較喜歡那種圖形介面方式的,像VC、BCB等IDE的除錯,但如果你是在UNIX平臺下做軟體,你會發現

執行程序的區別與聯絡

博主文章:https://www.cnblogs.com/D-DZDD/p/7203176.html 最近也是遇到了這個問題,想把pycharm裡面的log結果儲存到一個檔案裡面,但是呢我一個檔案有兩個類,呼叫Class Logger()時候,檔案儲存到txt只儲存了一些,剩下的只有我退

學習筆記之linux執行程序優缺點

Linux下的多執行緒 執行緒和程序相比的缺點和優點 優點: 多執行緒對資源的需求少,建立的代價比程序小 缺點:除錯困難,非常容易出錯 執行緒擁有獨立的程式計數器,獨立的棧空間,共享程序的全域性記憶體和堆記憶體,共享檔案描述符,共享虛擬記憶體。繼承訊號的處理可以訪問程序

執行程序的區別(小結)

很想寫點關於多程序和多執行緒的東西,我確實很愛他們。但是每每想動手寫點關於他們的東西,卻總是求全心理作祟,始終動不了手。 今天終於下了決心,寫點東西,以後可以再修修補補也無妨。 一.為何需要多程序(或者多執行緒),為何需要併發? 這個問題或許本身都不是個問題。但是對於沒有

執行程序的資源消耗對比

1、測試環境配置如下:        虛擬機器:Ubuntu16.04     4G記憶體    雙核處理器        執行環境python+flask+gunicorn+nginx          flask 、nginx和 gunicorn 安裝方法都非常簡單粗暴:

執行程序的區別

1.定義 程式: 只是一組指令的有序集合,是計算機硬碟上的一些檔案,是“死的” 程序:具有一定獨立功能的程式關於某個資料集合上的一次執行活動,程序是系統進行資源分配和排程的一個獨立單位,是“活的” 執行緒:是程序的一個實體,是CPU排程和分派的基本單位,

python的執行程序(一)

在進入主題之前,我們先學習一下併發和並行的概念: --併發:在作業系統中,併發是指一個時間段中有幾個程式都處於啟動到執行完畢之間,且這幾個程式都是在同一個處理機上執行。但任一時刻點上只有一個程式在處理機上執行。形象的點描述:一個人做很多事情,但同一時刻只能做一件事情。 --並行:當系統有一個CPU時,則程式的

一位10年Java程式設計師總結進階的你懂執行jvm優化嗎?

感謝朋友們的認可和指正。本文是有感而發,因為看過了太多坑人的部落格和書籍,感慨自己走過的彎路,不希望其他初學者被網上互相抄襲的部落格和東拼西湊的書籍浪費時間,想以一個相對巨集觀的視野來描述一個概念,力求通俗易懂,所以沒有深入太多細節,簡化了很多模型,給部分朋友造成了疑惑,說聲抱歉。也沒有配圖,都是抽

python執行程序的選擇問題

多執行緒與多程序的選擇問題 既然python中多執行緒和多程序都能夠進行非同步操作,那麼到底應該如何選擇 首先我們必須知道GIL全域性解釋鎖對執行緒的影響,其同一時間只能夠允許一個執行緒進入cpu進行執行,因此對於cpu密集型的程式並不適用於多執行緒操作 cpu密集型的功能對cp

Linux核心執行執行

一、執行緒的概念、理解及特點     1.執行緒的概念:         至今為止,Linux下還是沒有“真正的執行緒”。談到執行緒就不得不提到程序這概念,程序是系統中程式執行和資源分配的基本單位。每個程序都擁有自己的資料段,程式碼段和堆疊段,這就造成了程序在進行切換

python執行程序,協程概念及程式設計上的應用

1, 多執行緒    執行緒是程序的一個實體,是CPU進行排程的最小單位,他是比程序更小能獨立執行的基本單位。  執行緒基本不擁有系統資源,只佔用一點執行中的資源(如程式計數器,一組暫存器和棧),但是它可以與同屬於一個程序的其他執行緒共享全部的資源。  提高程式的執行速率

android 利用java執行io流,最快速度的下載伺服器檔案,android 實現apk下載展現通知欄

首先,我們得來說下多執行緒下載實現的大致思路,以及在使用多執行緒下載過程應該需要注意的問題。      多執行緒下載實現的大致思路:      大致思路是這樣的,也就是把整個一個檔案資源分為若干個部分,然後開啟若干個執行緒,並且使得每個執行緒負責下載每個子部分的檔案,由於

python執行程序,協程概念及程式設計上的應用!

1, 多執行緒 執行緒是程序的一個實體,是 CPU進行排程的最小單位,他是比程序更小能獨立執行的基本單位。 執行緒基本不擁有系統資源,只佔用一點執行中的資源(如程式計數器,一組暫存器和棧),但是它可以與同屬於一個程序的其他執行緒共享全部的資源。 提高程式的執行速率,上下文切換快