unity效能優化 CPU

2022-07-26 21:42:08 字數 4510 閱讀 4857

影響效能的因素:對於乙個遊戲來說,有兩種主要的計算資源:cpu和gpu,它們會互相合作,來讓我們的遊戲可以在預期的幀率和解析度下工作。cpu負責其中的幀率,gpu主要負責解析度相關的一些東西。本篇會介紹cpu的優化技巧~

作用:計算。主要是在蒙皮骨骼計算,布料模擬,頂點動畫,粒子模擬等,還有在各種頂點變換、光照、貼圖混合等。在每次繪圖前,我們都需要先準備好頂點資料(位置、法線、顏色、紋理座標等),然後呼叫一系列api把它們放到gpu可以訪問到的指定位置,最後,我們需要呼叫_gldraw*命令,來告訴gpu進行渲染。而呼叫_gldraw*命令的時候,就是一次draw call。影響cpu效率的因素主要有drawcall、物理元件、gc、**,cpu過高會影響幀率,卡頓、發熱嚴重,遊戲效能就會下降。

效能開銷:引擎模組效能開銷和自身**效能開銷。其中,引擎模組中又可細緻劃分為渲染模組、動畫模組、物理模組、ui模組、粒子系統、載入模組和gc呼叫等等。其中渲染模組、ui模組和載入模組,往往佔據了遊戲cpu效能開銷的top3。

優化:

drawcalls:draw call是渲染模組優化方面的重中之重,一般來說,draw call越高,則渲染模組的cpu開銷越大。

drawcall batching:unity在執行時可以將一些物體進行合併,從而用乙個批次呼叫來渲染他們。對於使用同乙個材質的物體,它們之間的不同僅僅在於頂點資料的差別,即使用的網格不同而已。我們可以把這些頂點資料合併在一起,再一起傳送給gpu,就可以完成一次批處理。unity中有兩種批處理方式:一種是動態批處理,一種是靜態批處理。但不論靜態批次還是動態批次都要求物件的材質是共享的,即不同材質的物件是無法進行批次的。而且要注意的一點:如果在指令碼中呼叫材質時,使用renderer.material會造成材質的拷貝,而使用renderer.sharedmaterial來呼叫則不會拷貝材質。對於動態批處理來說,好訊息是一切處理都是自動的,不需要我們自己做任何操作,而且物體是可以移動的,但壞訊息是,限制很多,可能一不小心我們就會破壞了這種機制,導致unity無法批處理一些使用了相同材質的物體。對於靜態批處理來說,好訊息是自由度很高,限制很少,壞訊息是可能會占用更多的記憶體,而且經過靜態批處理後的所有物體都不可以再移動了。

unity進行動態批處理對模型的要求很多:

1.動態批處理僅支援小於900頂點的網格物體,如果你的著色器使用頂點位置,法線和uv值三種屬性,那麼你只能批處理300頂點以下的物體;如果你的著色器需要使用頂點位置,法線,uv0,uv1和切向量,那你只能批處理180頂點以下的物體。而且未來頂點值有可能會變,不要依賴這個資料。

2.一般來說,所有物件都必須需要使用同乙個縮放尺度(可以是(1, 1, 1)、(1, 2, 3)、(1.5, 1.4, 1.3)等等,但必須都一樣)。但如果是非統一縮放(即每個維度的縮放尺度不一樣,例如(1, 2, 1)),那麼如果所有的物體都使用不同的非統一縮放也是可以批處理的。

3.擁有lightmap的物體含有額外(隱藏)的材質屬性,使用lightmap的物體不會批處理。多通道的shader會妨礙批處理操作。接受實時陰影的物體也不會批處理。

4.時刻警惕透明物體,透明物件要得到正確的渲染效果,就必須從後往前渲染(這裡不討論使用深度的方法),這意味著,透明物體幾乎一定會造成overdraws。盡可能把多張小紋理合併到一張大紋理(atlas圖集)中是乙個好主意。「generate mip maps」會為同一張紋理建立出很多不同大小的小紋理,構成乙個紋理金字塔。而在遊戲中可以根據距離物體的遠近,來動態選擇使用哪乙個紋理。這是因為,在距離物體很遠的時候,就算我們使用了非常精細的紋理,但肉眼也是分辨不出來的,這種時候完全可以使用更小、更模糊的紋理來代替,而這大量可以節省訪問的畫素的數目。但它的缺點是,由於需要為每乙個紋理建立乙個影象金字塔,因此它會需要占用更多的記憶體。「max size」決定了紋理的長寬值,如果我們使用的紋理本身超過了這個最大值,unity會對其進行縮小來滿足這個條件。這裡再重複一點,所有紋理的長寬比最好是正方形,而且長度值最好是2的整數冪。這是因為有很多優化策略只有在這種時候才可以發揮最大效用。

物理元件:從效能優化的角度考慮,物理元件能少用還是少用為好。1.設定乙個合適的fixed timestep(物理計算頻率)。2.就是不要使用網格碰撞器(mesh collider)。

gc優化:gc能釋放記憶體,但會加重cpu的負擔,因此對於gc的優化目標就是盡量少的觸發gc。gc不是用來處理引擎的assets(紋理啦,音效啦等等)的記憶體釋放的,gc也主要是針對mono的物件來說的,而它管理的也是mono的託管堆。引用型別,比如類的例項,字串,陣列等會被分配到託管堆。gc觸發:首先是堆的記憶體不足時,會自動呼叫gc。其次,程式設計人員手動的呼叫gc。

ui模組:

1.使用圖集:合理拆分ui圖集,區分公共圖集(常駐)和非公共圖集。太大容易造成冗餘載入,容易導致記憶體占用過大,導致記憶體視訊記憶體交換開銷。太小有容易導致視訊記憶體碎片影響效率。

3.layout group, canvas group元件,任何子節點變了父節點都會用getcompent找到laygroup

4.不需要互動的ui的raycast target關了。

5.盡量不用ui特效。

1.場景解除安裝:destory:引擎在切換場景時會收集未標識成「dontdestoryonload」的gameobject及其component,然後進行destroy。同時,**中的ondestory被觸發執行,這裡的效能開銷主要取決於ondestroy**函式中的**邏輯.resources.unloadunusedassets:一般情況下,場景切換過程中,該api會被呼叫兩次,一次為引擎在切換場景時自動呼叫,另一次則為使用者手動呼叫(一般出現在場景載入後,使用者呼叫它來確保上一場景的資源被解除安裝乾淨)。其耗時開銷主要取決於場景中asset和object的數量,數量越多,則耗時越慢。

2.場景載入:資源載入:其載入效率主要取決於資源的載入方式(resource.load或assetbundle載入)、載入量(紋理、網格、材質等資源資料的大小)和資源格式(紋理格式、音訊格式等)等等。instantiate例項化:在instantiate例項化時,引擎底層會檢視其相關的資源是否已經被載入,如果沒有,則會先載入其相關資源,再進行例項化,這其實是大家遇到的大多數「instantiate耗時問題」的根本原因,這也是為什麼我們在之前的assetbundle文章中所提倡的資源依賴關係打包並進行預載入,從而來緩解instantiate例項化時的壓力。場景載入盡量使用使用載入的方式。

**優化:

1.字串連線的處理。因為將兩個字串連線的過程,其實是生成乙個新的字串的過程。而之前的舊的字串自然而然就成為了垃圾。而作為引用型別的字串,其空間是在堆上分配的,被棄置的舊的字串的空間會被gc當做垃圾**。字串的鏈結使用stringbuilder進行鏈結。

2.盡量不要使用foreach,而是使用for。foreach其實會涉及到迭代器的使用,而據傳說每一次迴圈所產生的迭代器會帶來24 bytes的垃圾。那麼迴圈10次就是240bytes。

3.不要直接訪問gameobject的tag屬性。比如if (go.tag == 「human」)最好換成if (go.comparetag (「human」))。因為訪問物體的tag屬性會在堆上額外的分配空間。如果在迴圈中這麼處理,留下的垃圾就可想而知了。

4.使用物件「池」,以實現空間的重複利用。

5.最好不用linq的命令,因為它們會分配臨時的空間,同樣也是gc收集的目標。而且我很討厭linq的一點就是它有可能在某些情況下無法很好的進行aot編譯。比如「orderby」會生成內部的泛型類「orderedenumerable」。這在aot編譯時是無法進行的,因為它只是在orderby的方法中才使用。所以如果你使用了orderby,那麼在ios平台上也許會報錯。

6.最好不要頻繁使用getcomponent,尤其是在迴圈中(頻繁的呼叫getcomponent方法會造成cpu的開銷,但是對gc幾乎沒有影響。getcomponent只會在editor模式返回null時會造成額外的堆記憶體分配)。

7.善於使用onbecamevisible()(當renderer(渲染器)在任何相機上可見時呼叫onbecamevisible)和onbecameinvisible(),來控制物體的update()函式的執行以減少開銷。

8.使用內建的陣列,比如用vector3.zero而不是new vector(0, 0, 0);

9.對於方法的引數的優化:善於使用ref關鍵字。值型別的引數,是通過將實參的值複製到形參,來實現按值傳遞到方法,也就是我們通常說的按值傳遞。複製嘛,總會讓人感覺很笨重。比如matrix4x4這樣比較複雜的值型別,如果直接複製乙份新的,反而不如將值型別的引用傳遞給方法作為引數。

10.如果可以避免使用浮點型(float),盡量使用整形(int),盡量少用複雜的數學函式比如 sin 和 cos 等等。

Unity 效能優化

unity效能問題 vss virtual set size,虛擬耗用記憶體。它是乙個程序能訪問的所有記憶體空間位址的大小。這個大小包含了 一些沒有駐留在ram中的記憶體,就像mallocs已經被分配,但還沒有寫入。vss很少用來測量程式的實際使 用記憶體。rss resident set size...

cpu效能優化手段

1 cpu優化 快取 為了提高程式的執行的效能,現代cpu在很多方面對程式進行優化 例如 cpu的快取記憶體,盡可能的避免處理器訪問主記憶體的時間開銷,處理器大多會利用快取來提高效能 cpu快取分為 快取 l1 一級快取是cpu第一層快取記憶體 分為資料快取和指令快取 一般伺服器的cpu在32 4....

unity效能優化2

1 效能優化的是 低幀率或者高記憶體占用 通過unity profiler 我們知道誰占用cpu多少時間,遊戲如何使用記憶體 左側的是cpu使用情況,gpu,渲染,記憶體,聲音。下半部分顯示當前幀的詳細情況 1 如果遊戲執行的慢,我們首先看cpu,看誰占用了他大量的時間 a resources目錄下...