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