心如工畫師,能畫諸世間隘冲,五蘊悉從生闹瞧,無法而不造 。 ---------佛說
CPU與GPU
CPU作為中央處理器展辞,除了要負責(zé)邏輯計算外奥邮,還需要做內(nèi)存管理,顯示操作罗珍,因此隨著各種復(fù)雜App的出現(xiàn)洽腺,其實際運算的性能會大打折扣。
設(shè)計原由:為了提高圖形顯示效率以及復(fù)雜的圖形的顯示覆旱,設(shè)計出了GPU
主要功能:為幫助CPU分擔(dān)圖形顯示蘸朋。
CPU
藍色的Control微控制器,用于協(xié)調(diào)控制整個CPU的運行扣唱,包括取出指令藕坯,控制其他的模塊運行等;
綠色的ALU(Arithmetic Logic Unit)為算數(shù)邏輯單元噪沙,用于數(shù)學(xué)以及邏輯運算炼彪;
橙色的Cache和DRAM分別為緩存和RAM,用戶存儲信息
CPU控制器比較復(fù)雜正歼,ALU數(shù)量較少辐马,因此CPU擅長各種復(fù)雜的邏輯運算,但不擅長數(shù)學(xué)尤其浮點運算
GPU
GPU和CPU唯一不同的是GPU的ALU模塊占據(jù)了相當(dāng)大的板塊局义,為什么說GPU中ALU占據(jù)了這么大的板塊呢齐疙?它主要的原因就是因為ALU擅長數(shù)學(xué)運算以及邏輯運算。而我們都知道GPU是為了提高圖形的顯示效果旭咽,為什么說ALU擅長數(shù)學(xué)運算以及邏輯運算就能夠處理好圖形的顯示呢贞奋?首先我們都知道我們的屏幕上面之所以可以看到五顏六色的圖片的話,手機它自己是不知道把這么一張五顏六色的圖片顯示出來的穷绵,它只會根據(jù)我們傳過去的像素點來顯示轿塔,屏幕是由一個一個的像素點而組成,那么它只需要知道屏幕上的每一個像素點是什么顏色即可,從而達到顯示的效果勾缭。我們都知道在手機上顯示顏色的時候我們都會用一個16進制的數(shù)來表示揍障,比如說剛開始有一塊A區(qū)域顏色是#FFFFFFFF,這個時候我們要將白色的A區(qū)域轉(zhuǎn)換成黑色的#22222222,在這個轉(zhuǎn)換的過程中是一個數(shù)學(xué)的邏輯運算,對于數(shù)學(xué)運算的ALU是比較擅長的俩由,這也恰恰說明了在GPU中ALU為啥占據(jù)了這么大的一個板塊毒嫡。
XML布局顯示至屏幕流程
首先我們在XML文件里面定義了一個button,這個button包含了一些height 幻梯,width,background...等一些這樣的信息兜畸,然后通過LayoutInflater解析布局將解析出來的這些信息加載進內(nèi)存,然后CPU將LayoutInflater解析出來的信息通過計算處理成位圖碘梢,緊接著CPU將處理出來的這個位圖交給GPU咬摇,GPU呢會對這個位圖做一些刪格化,什么是刪格化煞躬?肛鹏??恩沛?在扰,比如說我們的這個button,長是50dp雷客,高是50dp,背景是紅色芒珠,GPU拿到CPU交給它的這個寬高50dp的位圖以后,GPU首先會將這個紅色區(qū)域轉(zhuǎn)化成一個一個的紅色像素點佛纫,也就是說GPU將位圖轉(zhuǎn)化成像素點的過程即為刪格化。刪格化以后GPU將轉(zhuǎn)化成的像素點傳遞給屏幕從而達到顯示的效果总放,這個時候我們手機屏幕上面會顯示出來一個寬高50dp呈宇,背景是紅色button。
FPS概念
12fps:畫面幀率高于每秒約10-12幀時局雄,眼睛會認為它是連貫的甥啄。
24fps:有聲電影拍攝一般為24幀
30fps:早期動態(tài)電子游戲,一般會在每秒30幀左右
60fps:手機交互過程中炬搭,需要接觸和反饋蜈漓。需要60幀才能達到不卡頓的效果(比如說我們手機上面要顯示一個button,這個button顯示到屏幕的過程中如果每秒中繪制少于60幀的化宫盔,用戶就會覺得有卡頓的效果)
了解了FPS概念以后我們需要了解安卓系統(tǒng)每隔16ms融虽,它就要發(fā)送一次Vsync信號對UI進行一次渲染,如果每次都能成功的話灼芭,就會達到流暢有额,也就是我們剛說的每秒60幀。這個16ms是怎么來的呢?因為每秒鐘要達到60幀的效果巍佑,UI我們才看起來不會卡頓這也意味著每秒要是繪制60幀茴迁,1秒=1000ms,1000/60=16ms萤衰,這也就是為啥安卓系統(tǒng)要每隔16ms要發(fā)送一次vsync信號對UI進行一次渲染堕义。這也充分說明如果我們寫的自定義View或者使用系統(tǒng)的控件組合的自定義View或者我們寫的XML布局文件,如果在16ms內(nèi)完成不了繪制脆栋,客戶就會覺得卡頓倦卖。
優(yōu)化目標(biāo)
1 CPU減少XML轉(zhuǎn)換成對象的時間
2 GPU減少重復(fù)繪制
在實際開發(fā)中以上兩步必須要在16ms內(nèi)完成,否則用戶會感覺到卡頓效果筹吐。
記住是16ms內(nèi)完成繪制 ,記住是16ms內(nèi)完成繪制 糖耸,記住是16ms內(nèi)完成繪制?記住是16ms內(nèi)完成繪制 ,重要的事情說四邊
過渡繪制的概念
GPU每個16ms發(fā)送一個vsync信號畫一次丘薛,如果CPU傳遞過來的圖形有重復(fù)的位置嘉竟,會造成用戶智能看到頂層畫面,而底層畫面則被遮蓋洋侨,底層畫面的繪制雖然用戶無法看到舍扰,但同樣也占據(jù)了計算資源,造成不必要的浪費希坚,這種情況叫過度繪制边苹。
過度繪制查看工具
????????????????????打開開發(fā)人員選項,開啟調(diào)試GPU過度繪制裁僧,顏色說明个束,淺藍色表示只有一層繪制,淺綠色表示只有兩層繪制聊疲,粉色表示有三層繪制茬底,紅色表示4層或者更多繪制,一般情況下我們只需要關(guān)注紅色區(qū)域的布局文件或者自定義View的代碼获洲,即優(yōu)化這個區(qū)域的代碼即可達到性能優(yōu)化的效果阱表,接下來我們用一個示例程序來演示過度繪制以及優(yōu)化方案。
XML布局代碼
運行效果圖如下
分析贡珊,當(dāng)前這個頁面存在過度繪制的情況最爬,頁面出現(xiàn)粉紅色的主要原因,是XML里面嵌套了太多的層級门岔。下面對示例代碼中XML層級做出具體的分析爱致。
首先GPU在繪制的過程中會繪制一個LinearLayout,緊接著又會繪制imageView和LinearLayout寒随,LinearLayout繪制完畢以后又有一個android:background="@android:color/darker_gray"的背景顏色蒜鸡,緊接著會繪制這個灰色的背景色胯努,背景色繪制完畢以后緊接著又會繪制RelativeLayout和一個TextView和一個android:background="@android:color/white"白色背景,RelativeLayout繪制完畢以后又會繪制android:background="@android:color/white"白色背景逢防,白色背景繪制完畢以后緊接著又繪制兩個TextView叶沛,這樣多層級的嵌套是導(dǎo)致過度繪制的主要原因,過度繪制導(dǎo)致了GPU資源的浪費忘朝。
解決方案
減少布局嵌套層級以達到同樣的功能效果灰署,修改以后的代碼以及運行效果如下圖。