51
PRACTICAL GUIDE TO OPTIMIZATION IN UNITY Valentin Simonov Field Engineer / Unity Technologies [email protected]

Practical guide to optimization in Unity

Embed Size (px)

Citation preview

Practical guide to optimization in unityValentin SimonovField Engineer / Unity [email protected]

1

ABOUT MEValentin Simonov Field EngineerEmail: [email protected]

I help studios make games betterI teach people how to use Unity efficiently(conferences, trainings, blog posts, translated a book on shaders)I maintain https://github.com/TouchScript/

EFFICIENCY

1. Why is it not working?2. Why is it so slow?

1. Why is it not working?2. Why is it so slow?

LETS STARTOPTIMIZING

ALGORITHMGet data about your project (tools)Interpret that data (knowledge)Make a list of possible optimizations (management)Perform necessary* optimizations (business)

WE CAN HELP YOU WITHGet data about your project (tools)Interpret that data (knowledge)Make a list of possible optimizations (management)Perform necessary* optimizations (business)

TOOLSHow to get correct data and eliminate guess work.Unity ProfilerUnity Frame DebuggerUnity Memory Profiler ( https://bitbucket.org/Unity-Technologies/memoryprofiler )Platform tools

KNOWLEDGEHow to make correct decisions based on collected data.Blogs, forums, learning materials ( https://unity3d.com/learn/tutorials/topics/best-practices )Videos from conferencesTrainings

LEARN ALL THE TOOLS

UNITY PROFILERShows code execution time and GC allocationsCan be connected to a remote deviceDeep Profile in Editor

OVERHEADProfiler.BeginSample() / Profiler.EndSample()

Gfx.WaitForPresentProfiler.BeginSample() / Profiler.EndSample()

FRAMECPU HAS TO WAITPREVIOUS FRAME GPU WORKTHIS FRAME GPU WORK

TEST ON DEVICEAlways test on target device!Editor code is differentTarget hardware is different

UNITY FRAME DEBUGGER

UNITY MEMORY PROFILERhttps://bitbucket.org/Unity-Technologies/memoryprofilerOpen this project in UnityConnect to a development buildGrab snapshotHave fun!

privateTexture2Dtex;varbundle=AssetBundle.LoadFromFile(...);tex=bundle.LoadAsset(img");bundle.Unload(false);

varbundle=AssetBundle.LoadFromFile(...);vartexture= bundle.LoadAsset(img");bundle.Unload(false);

staticListlist;var bundle=AssetBundle.LoadFromFile();list.Add( bundle.LoadAsset(img"));bundle.Unload(false);

PLATFORM TOOLSApple Instruments: Time Profiler, Allocations

Shows everythingAccurate stack traceCPU time on deviceCan save/load traces

EXAMPLEStatement: The game is leaking memory.Unity Profiler shows memory growing... but doesnt show any allocations from scripts.

ASK MEANINGFUL QUESTIONS

DO YOU USE THESE TOOLS?Do you know these tools?Do you use them?Does your team use them?

GET ALL THE KNOWLEDGE

26

TRUST NO ONEThe trouble with quotes on the Internet is that you can never know if they are genuine.

Abraham Lincoln

27

TRUST NO ONEInternet is full ofOutdated informationAdvice not applicable to your platformInformation which is just wrong

STATIC BATCHINGLight and heavy draw calls.

TEST EVERYTHING** on your target platform/device

RESOURCES FOLDERUsing Resources folder is generally not advised:All Resources folders are packed in a monolithic binaryRebuilt every time even if nothing has changed4 Gb size limit, uncompressedMore assets -> slower loadingAt start time Unity builds index and always keeps it in memory

31

TEST 1: RESOURCES FOLDER12 000 1px images in ResourcesLook for ResourceManager::TransferCPU time depends on device (iPhone 4s on the pic below)

32

LEARN FROM TESTSWhat are these shaders?

INCLUDED SHADERSInternal-ErrorShaderNormal-VertexLitNormal-DiffuseInternal-StencilWriteInternal-DepthNormalsTextureInternal-PrePassLightingInternal-ScreenSpaceShadowsInternal-CombineDepthNormalsInternal-BlitCopyInternal-DeferredShadingInternal-DeferredReflectionsInternal-MotionVectorsInternal-FlareInternal-HaloInternal-GUITextureClipInternal-GUITextureClipTextInternal-GUITextureInternal-GUITextureBlitSprites-DefaultUI-DefaultUI-DefaultFontCubeBlurCubeCopyCubeBlendSkybox-Procedural

LEARN FROM TESTSKeep in mind platform specific behaviors.For example, that iOS caches compiled shaders.

TEST 2: INSTANTIATEQuestion: What is the fastest way to dynamically create 1000 complex objects?Complex object 10 children with 10 components each.

Create 10 children, add 10 components to each, repeat.Create 1 template object with 10 children, clone it 999 times.Instantiate a prefab, repeat.

Target device: iPhone 6, Unity 5.4.1

TEST 2: INSTANTIATECreate 10 children, add 10 components to each, repeat.1562.250 msCreate 1 template object with 10 children, clone it 999 times.451.394 msInstantiate a prefab, repeat.485.250 msClone a prefab, instantiate the clone 999 times.432 ms

TEST 2: INSTANTIATECreate 10 children, add 10 components to each, repeat: 1562.250 ms

TEST 2: INSTANTIATE2. Create 1 template object with 10 children, clone it 9999 times. 451.394 ms

TEST 2: INSTANTIATE

Create 1 template object with 10 children, clone it 999 times. 440.593 451.394 msClone a prefab, instantiate the clone 999 times. 422.5 432 msInstantiate a DISABLED prefab, repeat. 412.5 422.5 ms

KNOW WHERE ASSETS LIVE

KNOW WHERE ASSETS LIVE

THIS GUY!

KNOW WHERE ASSETS LIVETheres native (C++) and managed (C#) memoryAssets live in native memoryManaged memory has light wrappers for assets

Texture2D myTexture = (a) myTexture = null; wrapper is GCd, texture data is stuck(b) Destroy(myTexture); wrapper is stuck, texture data is freed(c) Resources.UnloadUnusedAssets(); destroys stuck assets(d) GC.Collect(); GCs stuck wrappers (at this point destructors are called)

EXAMPLE: WWWWWW www = new WWW() -> allocate bufferswww.Dispose() -> DestroyWWW()-> release buffersGC(?)-> www.~WWW() -> DestroyWWW()-> release buffers

WWW wrapperWWW dataManaged

UNITY IS A C++ ENGINEUnity is a C++ engine with a .NET virtual machineCalling Managed functions from Native involves some overheadEvery Awake/Start/Update* call is a call from Native to Managed... even empty ones o.OAt some point you will start noticing this overhead

10000 UPDATE CALLShttps://blogs.unity3d.com/2015/12/23/1k-update-calls/

KNOW WHAT APIs DOFind, FindObjectOfType super slow!Camera.main doesnt cache the main cameraAPIs which return arrays allocate memory every time

READ THE SOURCEUnity open source projectshttps://bitbucket.org/Unity-Technologies/uihttps://github.com/Unity-Technologies/PostProcessingUnityEngine.dll -> ILSPYhttp://va.lent.in/unity-make-your-lists-functional-with-reorderablelist/Time Profiler instrument and other tools.

READ THE SOURCE

QUESTIONS?Valentin SimonovField Engineer / Unity [email protected]

51