Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

【Unite 2017 Tokyo】Unity最適化講座 ~スペシャリストが教えるメモリとCPU使用率の負担最小化テクニック~

30,315 views

Published on

講演者:イアン・ダンドア(Unity Technologies)

こんな人におすすめ
・メモリ使用を削減したいプログラマー、開発者全般

受講者が得られる知見
・メモリ、GPU、CPUのリソースの無駄使いを発見し、削減するテクニック

講演動画:https://youtu.be/jHpkoJAMDGE

Published in: Technology
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

【Unite 2017 Tokyo】Unity最適化講座 ~スペシャリストが教えるメモリとCPU使用率の負担最小化テクニック~

  1. 1. Ian Dundore
 LeadDeveloperRelationsEngineer,Unity
  2. 2. Optimizing Unity
 SavingCPU&Memory,becauseyoucan.
  3. 3. What’ll we cover today? • Primary focus will be CPU optimization. • Transform component • Animator • Physics • Finish with some tips for saving memory.
  4. 4. Always, always profile!
  5. 5. Transforms! Not as simple as they look.
  6. 6. Transforms? • Every GameObject has one. • When they change, they send out messages. • C++: “OnTransformChanged” • When reparented, they send out MORE messages! • C#: “OnBeforeTransformParentChanged” • C#: “OnTransformParentChanged” • Used by many internal Unity Components. • Physics, Renderers, UnityUI…
  7. 7. OnTransformChanged? • Sent every time a Transform changes. • Three ways to cause these messages: • Changing position, rotation or scale in C# • Moved by Animators • Moved by Physics • 1 change = 1 message!
  8. 8. Why is this expensive? • Message is sent to all Components on Transform & all Children • Yes, ALL. • Physics components will update the Physics scene. • Renderers will recalculate their bounding boxes. • Particle systems will update their bounding boxes.
  9. 9. void Update() { transform.position += new Vector3(1f, 1f, 1f); transform.rotation += Quaternion.Euler(45f, 45f, 45f); }
  10. 10. void Update() { transform.position += new Vector3(1f, 1f, 1f); transform.rotation += Quaternion.Euler(45f, 45f, 45f); } X
  11. 11. void Update() { transform.SetPositionAndRotation( transform.position + new Vector3(1f, 1f, 1f), transform.rotation + Quaternion.Euler(45f, 45f, 45f) ); }
  12. 12. Collect your transform updates! • Many systems moving a Transform around? • Add up all the changes, apply them once. • If changing both position & rotation, use SetPositionAndRotation • New API, added in 5.6 • Eliminates duplicate messages
  13. 13. What system has lots of moving Transforms?
  14. 14. 100 Unity-chans! • Over 15,000 Transforms! • How will it perform?
  15. 15. PerformanceTest (Unity 5.6) times in ms iPad Air 2 Macbook Pro, 2017 Unoptimized 33.35 6.06 Optimized 26.96 3.37 Timings are only from Animators
  16. 16. “Optimized”?
  17. 17. What does it do? • Reorders animation data for better multithreading. • Eliminates extra transforms in the model’s Transform hierarchy. • Need some, but not all? Add them to the “Extra Transforms” list! • Allows Mesh Skinning to be multithreaded.
  18. 18. “Optimized”?
  19. 19. Physics!
  20. 20. What affects the cost of Physics? • Two major operations that cost time: • Physics simulation • Updating Rigidbodies • Physics queries • Raycast, SphereCast, etc.
  21. 21. Scene complexity is important! • All physics costs are affected by the complexity and density of a scene. • The type of Colliders used has a big impact on cost. • Box colliders & sphere colliders are cheapest • Mesh colliders are very expensive • Simple setup: Create some number of colliders, cast rays.
  22. 22. Cost of 1000 Raycasts times in ms 10 Colliders 100 Colliders 1000 Colliders Sphere 0.27 0.48 1.53 Box 0.34 0.42 1.67 Mesh 0.37 0.53 2.27 Objects created in a 25-meter sphere
  23. 23. Density is important! times in ms 10 meters 25 meters 50 meters 100 meters Sphere 2.13 1.28 1.08 0.78 1000 Raycasts through 1000 Spheres
  24. 24. Why is complexity important? • Physics queries occur in three steps. • 1: Gather list of potential collisions, based on world-space. • 2: Cull list of potential collisions, based on layers. • 3: Test each potential collision to find actual collisions.
  25. 25. Why is complexity important? • Physics queries occur in three steps. • 1: Gather list of potential collisions, based on world-space. • Done by PhysX (“broad phase”) • 2: Cull list of potential collisions, based on layers. • Done by Unity • 3: Test each potential collision to find actual collisions. • Done by PhysX (“midphase” & “narrow phase”) • Most expensive step
  26. 26. Reduce number of potential collisions! • PhysX has an internal world-space partitioning system. • Divides world into smaller regions, which track contents. • Longer rays may require querying more regions in the world. • Benefit of limiting ray length depends on scene density! • Use maxDistance parameter of Raycast! • Limits the world-space involved in a query. • Physics.Raycast(myRay, 10f);
  27. 27. Control maxDistance! times in ms 10 meters 25 meters 50 meters 100 meters 1 meter 1.85 1.02 0.49 0.50 10 meters 2.10 1.19 0.91 0.53 100 meters 2.11 1.36 1.07 0.77 Infinite 2.13 1.28 1.08 0.78 1000 Raycasts through 1000 Spheres
  28. 28. Edit the physics layers! • Consider making special layers for special types of entities in your game • Help the system cull unwanted results.
  29. 29. Trade accuracy for performance • Reduce the physics time-step. • Running at 30FPS? Don’t run physics at 50FPS! • Reduces accuracy of collisions, so test changes carefully. • Most games can accept timesteps of 0.04 or 0.08
  30. 30. [RequireComponent(typeof(Rigidbody))] class MyMonoBehaviour : MonoBehaviour { void Update() { transform.SetPositionAndRotation(…); } }
  31. 31. [RequireComponent(typeof(Rigidbody))] class MyMonoBehaviour : MonoBehaviour { void Update() { transform.SetPositionAndRotation(…); } } X
  32. 32. [RequireComponent(typeof(Rigidbody))] class MyMonoBehaviour : MonoBehaviour { Rigidbody rb; void Awake() { rb = GetComponent<Rigidbody>(); } void Update() { rb.MovePosition(…); rb.MoveRotation(…); } }
  33. 33. Common errors: Rigidbody movement • Do not move GameObjects with Rigidbodies via their Transform • Use Rigidbody.MovePosition, Rigidbody.MoveRotation 500 objects MovePosition & MoveRotation Transform SetPositionAndRotation FixedUpdate 0.45 0.90
  34. 34. Memory time!
  35. 35. IL2CPP Platforms: Memory Profiler • Available on Bitbucket • https://bitbucket.org/Unity-Technologies/memoryprofiler • Requires IL2CPP to get accurate information. • Shows all UnityEngine.Objects and C# objects in memory. • Includes native allocations, such as the shadowmap
  36. 36. Examining a memory snapshot
  37. 37. Examining a memory snapshot
  38. 38. Examining a memory snapshot ?!
  39. 39. Examining a memory snapshot
  40. 40. This is a shadowmap… do we need one?
  41. 41. Look at the HideFlags
  42. 42. HideAndDontSave? • Value in the HideFlags enum. • Includes 3 values: • HideInHierarchy • DontSave • DontUnloadUnusedAsset • Mistake: Setting in-game assets to use this HideFlag. • Assets loaded with HideAndDontSave flag will never be unloaded!
  43. 43. Examining a memory snapshot
  44. 44. Examining a memory snapshot
  45. 45. Examining a memory snapshot
  46. 46. Check your assets! • Common for artists to add assets in very high resolutions. • Does Unity-chan’s hair really need three 1024x1024 textures? • Reduce size? Achieve the same effect some other way?
  47. 47. Beware of Asset Duplication • Common problem when placing Assets into Asset Bundles • Assets in Resources & an Asset Bundle will be included in both • Will be seen as separate Assets in Unity • Separate copies will be loaded into memory • Also happens when Asset Dependencies are not declared properly
  48. 48. Asset Dependencies Material A Material B Texture (shared) Shader A Shader B
  49. 49. Asset Dependencies Material A Material B Texture (shared) Shader A Shader B
  50. 50. Asset Dependencies Material A Material B Texture (shared) Shader A Shader B
  51. 51. Asset Dependencies Material A Material B Texture (shared) Shader A Shader B Texture (shared)
  52. 52. Asset Dependencies Material A Material B Texture (shared)Shader A Shader B
  53. 53. Runtime texture creation • Creating textures procedurally, or downloading via the web? • Make sure your textures are non-readable! • Read-write textures use twice as much memory! • Use UnityWebRequest — defaults to non-readable textures • Use WWW.textureNonReadable instead of WWW.texture
  54. 54. Marking textures non-readable • Pass nonReadable as true when calling Texture2D.LoadImage • Texture2D.LoadImage(“/path/to/image”, true); • Call Texture2D.Apply when updates are done • Texture2D.Apply(true, true); • Updates mipmaps & marks as non-readable • Texture2D.Apply(false, true); • Does not update mipmaps, but does mark as non-readable
  55. 55. Thank you!

×