【Android 性能優化】佈局渲染優化 ( CPU 與 GPU 架構分析 | 安卓佈局顯示流程 | 視覺與幀率分析 | 渲染超時卡頓分析 | 渲染過程與優化 )





一、 CPU 在圖形處理領域的情況



GPU 出現前 CPU 在圖形處理領域的情況 :


① 承擔工作多 : GPU 沒有出現之前 , CPU 要承擔很多工作 , 如邏輯運算 , 內存管理 , 顯示控制 , 界面渲染 等操作 ;

② 設備弊端 : 不能顯示覆雜的圖形 , 不能運行渲染逼真的遊戲 , 如大型 3D 遊戲等 ;

③ CPU 在圖形領域的性能瓶頸 : CPU 即使超過 2GHz 的主頻 , 其運算能力並不能完全發揮出來 , 無法顯示覆雜畫面 , 不能提高圖形繪製的質量 ;


鑑於上述 CPU 的各種弊端 , 就有了 GPU 的設計 , CPU 將顯示相關的計算交給 GPU 完成 ;





二、 CPU 與 GPU 架構對比



在這裏插入圖片描述

CPU 與 GPU 架構 :


① 控制單元 ( 黃色部分 ) : 控制器 , 控制 CPU 運行工作 , 執行如 取出指令操作 , 控制其它模塊運行 ;

② 計算單元 ( 綠色部分 ) : 算術邏輯單元 , 負責數學運算 , 邏輯運算 ;

③ 存儲單元 ( 橙色部分 ) : Cache 高速緩存器 , DRAM , 用於存儲 CPU 運算信息 ;



CPU 與 GPU 對比 :


① 邏輯算術運算 : 圖像處理時 , 大量使用邏輯運算 , 如 RGB 像素值的位運算 ; GPU 的計算單元多於 CPU , 因此 GPU 的邏輯運算能力強於 CPU ;

② 程序執行邏輯 : CPU 中控制單元與存儲單元功能強大 , 控制程序運行的能力遠遠高於 GPU ;

③ 總結 : GPU 適合用於大量的複雜的算術邏輯計算 , 如圖像運算 , 聲音運算等 ; CPU 適合用於控制系統 , 應用運行 ;





三、 Android 佈局顯示到屏幕流程



Android 佈局顯示到屏幕流程 :


① 定義佈局中的組件 : 在 xml 佈局文件中定義 ImageView 佈局 ;

② 加載組件到內存 : 通過 LayoutInflater 將該 ImageView 組件解析成 ImageView 對象 , 加載到內存中 , 該對象中封裝了組件位置 , 顯示圖片等信息 ;

③ CPU 處理 : 將上述 ImageView 對象進行計算處理 , 最終得到該組件對應的多維向量圖形 ( 使用向量表示的圖形 ) ;

④ GPU 處理 : GPU 接收上述多維向量圖形 , GPU 將該向量圖進行柵格化 , 將向量圖轉爲位圖 ( 矢量圖轉爲像素圖 ) , 計算出對應屏幕上每個像素點顯示的值 ;

⑤ 顯示器顯示 : GPU 向顯示器推送位圖 , 會判定前面的 44 個步驟花費時間是否小於 16ms , 如果小於該值 , 那麼就顯示該位圖 , 如果大於該值 , 那麼不繪製 , 等待下一幀位圖繪製完成 , 這是爲了避免顯示卡頓而設計的機制 , 雖然丟了一幀數據 , 但是顯示很流暢 ;





四、 人眼的視覺相關分析



1 . Android 刷新幀率 :

① 最低流暢幀率 : 保持畫面流暢的最低幀率是 60FPS , 當幀率低於 60 FPS 時 , 就會畫面卡頓的感覺 ;

② 60 幀率對應的每一幀刷新間隔 : 100060=16.66\dfrac{1000}{60} = 16.66 , 即每隔 16.66 毫秒刷新一次 ;

③ Android 設備刷新機制 : Android 中每隔 16ms 就會發出 VSYNC 信號通知屏幕該進行渲染 , 每次渲染的時間都必須小於 16 毫秒 , 才能保證 60 FPS 的幀率 ; 如果渲染時間大於 16 毫秒 , 就無法保證 60 FPS 的幀率, 此時就會造成卡頓 ;



2 . 人眼對於各個幀率的接受程度 :


① 12 FPS : 達到這個幀率 , 人眼可以認爲該圖像是連續的動作 , 如 GIF 圖像 , 翻動作小人書等 ;

② 24 FPS : 初期的電影動畫的幀率 , 勉強接收 ;

③ 30 FPS : 早期的電子遊戲 , 要求高於電影 ;

上面的三種都是人與視頻內容不交互 , 或少量交互 , 人感覺不出來卡頓 ;

④ 60 FPS : 在交互頻繁的遊戲中 , 低於 60 FPS , 是可以感覺出來的 , 因此動作類的遊戲儘量都要達到 60 FPS ;

⑤ 60 FPS 以上 : 60 FPS 與 144 FPS 是等效的 , 人眼察覺不到這個差異 ;


打遊戲時 , 感覺很卡 , 說明幀率低於 60 幀了 , 越低遲滯感越強烈 ;





五、 渲染超時卡頓分析



1. VSync 信號 : Android 每隔 16 毫秒發出 VSync 信號 , 屏幕接收到該信號時 , 開始顯示渲染好的位圖 , CPU 和 GPU 開始渲染新的圖像 ;


2. 渲染與顯示時間固定 : 渲染開始 與 屏幕繪製的時間都是固定的 , 就是 VSync 信號發出時間 , 並且其間隔必須是 16 毫秒 , 在固定的時間開始渲染 , 在固定的 16 毫秒之後 , 顯示到屏幕中 , 這樣就是固定的 60Hz 的屏幕刷新頻率 ;


3. 渲染提前完成 : 渲染可以提早完成 , 如 CPU 和 GPU 在 10 毫秒時已經渲染完畢 , 將向量圖柵格化後的位圖傳遞給屏幕 , 此時等待 6 毫秒後 , 屏幕觸發顯示操作 , 將已經渲染完畢的位圖顯示出來 ;


4. 顯然超時未完成 : 在某個固定的時間 , 開始渲染圖片 , CPU , GPU 對佈局組件對應畫面進行渲染後 , 如果從開始渲染 , 到顯示器顯示之間的時間間隔超過了 16 毫秒 , 屏幕在 16 毫秒的時刻接收 VSync 信號觸發顯示 , 但是此時還處於渲染階段 , 沒有將位圖傳遞給屏幕 , 因此仍然顯示上一幀圖片 , 這裏就少了一幀 , 變成了 59 Hz 的刷新頻率 , 如果這種超時很多 , 變成 40Hz , 30Hz , 那就非常卡了 ;

在這裏插入圖片描述

上圖中應該繪製 4 幀數據 , 但是實際上只繪製了 3 幀 , 實際刷新率少了一幀 ;





六、 渲染過程與優化



1. 渲染耗時分析 : 在開始渲染到顯示的 16 毫秒時間內 , 主要有 33 個比較大塊的時間 , 33 個耗時操作分別與 CPU 和 GPU 相關 ;


① 佈局轉換工作 : CPU 將佈局中的 UI 組件對象轉爲多維向量圖形 ( 紋理 / 多邊形 / 向量 ) ;

② 圖像傳遞工作 : CPU 傳遞向量圖形給 GPU , CPU 與 GPU 之間數據傳遞非常耗時 ;

③ 圖像繪製工作 : GPU 將該向量圖形轉爲由像素點組成的位圖 ;



2. 渲染優化 : 優化這裏有引出了佈局渲染優化 , 從上述 33 個角度去進行渲染優化 :


① 佈局轉換優化 : 減少 CPU 將 UI 組件對象轉爲多維向量圖形的耗時 ;

② 圖像傳遞優化 : 減少 CPU 傳遞給 GPU 的圖像數據 ;

③ 圖像繪製優化 : GPU 會執行 CPU 傳遞過來的任何計算工作 , 即使出現了圖像覆蓋重繪 , GPU 也會照常執行 , 減少 GPU 的圖像覆蓋重繪 ;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章