I’m profiling a game on the iPhone4 and I’m finding the FPS is not so hot right now. I’ve been using the profiler to optimize draw calls and physics performance, but I’m seeing an item called “overhead” that is taking up a shockingly large percentage of my CPU time (~9ms when our total budget is 33ms per frame).
Unity’s documentation doesn’t explain what “overhead” is; does anyone have any insights? I had guessed it was like “base engine overhead”, but it isn’t contant and fluctuates based on the currently loaded level. And more importantly, does anyone know how to reduce the time taken up by overhead?
The Overhead presents usually vsync. especially on iOS where you can not turn of vsync. Profiling overhead might be included too, but usually it isn’t that big (for actual builds), also if you are GPU bound, then it might appear as overhead, but more often you will see it under Camera.Present. 9ms might be perfectly fine for vsync.
- In the Profiler, the Overhead is the total frame time minus the duration of everything else that is actively measured.
- It’s usually related to the internal processing of the scene. The complexer the scene, the more Overhead it will produce.
- It also accounts for the vertical synchronization, that can be set to a fixed duration with Application.targetFrameRate.
- Issues that could cause Overhead spikes are Memory warnings - When iOS throws memory warnings that increases the app Overhead. Thus when the iOS player constantly crosses the memory warning line, that will cause lots of large Overhead spikes. Use Instruments Activity Monitor to visualize these warnings as flags on top of the timeline.
The complexity of the scene doesn’t refer directly to the amount of objects that compose it, but to the processing in general. If you have lots of objects, processing all of them will take more time than just a few. But more important the different engine subsystem tasks on those objects (in this case, tasks that are not being actively measured in the Profiler) will be added to this complexity increasing the Overhead. Depending on the work performed this increase could be significative or not. So it’s not possible for us to provide statistics on the complexity of the scene, it depends on many factors.
The Profiler’s hierarchy is populated with the processes that most probably will consume important resources, but there will still remain lots of hidden tasks. In order to find what is adding more complexity or processing to the scene, you could remove or change “aspects” of the scene, one by one, then profile and see how that affects the Overhead. With aspects I mean groups of objects that are processed by some subsystem, i.e. 3D or 2D physics, navmesh, sprites, lighting, scripts and plugins, rendering, GUI, audio or video, particles, etc. The aspects could include settings used by the subsystems. You might find one of these is considerably affecting the performance, and then you can optimize it.
You can also check your project against some of these general performance tips/considerations that our Support team has compiled, and that might help reducing the Overhead as well:
- FPS is determined by CPU and GPU usage.
- CPU : Physics, Game code, Skinning (when not done in GPU), Particles, Raycasting (Flares)
- GPU : Fillrate, Shaders, Drawcalls, Image Effects.
- Garbage Collection.
- Remove all empty event callbacks (OnGUI, LateUpdate, Update, etc) from scripts.
- Increase the fixedTimeStep (Physics timestep) to reduce the number of time physics simulation is updated.
- Set the Maximum Allowed Timestep in the Time manager to cap the time spent on physics in the worst case scenario.
- All static moving objects must remain static in the game. If you need to alter them in any way (change size, position, orientation, disable/enable) you should make them Kinematic * Rigibodies.
- For each Flare in your scene Unity performs a Raycast from the Camera position. Make sure only the Flares that should be active are enabled in the scene.
- Remove all unneeded curves (e.g A curve with a constant scale of 1,1,1.) and redundant keyframes from your AnimationClips.
- Use QualitySettings to match the hardware of the device. Try reducing Anti Aliasing, reducing the Shadow distance, and changing the max LOD values.
- Uncompressed AudioClips require less CPU for playback. Use this setting for small clips that don’t use too much space in memory.
- Use HashSet instead of Lists if you need to use Find or Contains every frame. It is a data structure designed for quick searching.
- Cache references instead of performing unnecessary searches.
- Avoid using multiple cameras if possible. Having a second camera will unfortunately have the implication that the culler has to process the scene twice - even if you set a different * layer for one of the cameras.
- Use ParticleSystems for rendering sprites and billboards (e.g grass)
- If you are need to constantly modify a mesh, make sure to call MarkDynamic() on the mesh to allow Unity to optimize the mesh for frequent changes.
- Reduce memory allocations to reduce GC hiccups. Use the GC Alloc column in the Profiler to find code allocating memory.
- Using object pooling for ephemeral objects is faster than creating and destroying them, because it makes memory allocation simpler and removes dynamic memory allocation * * * overhead (mono needs to look at the state of the memory to allocate) and Garbage Collection, or GC.
- Use System.RuntimeMethodHandle.GetFunctionPointer to pre-jit functions.
- If you have a scaled meshcollider the mesh collider will be baked on the main thread which can stall your game. Avoid doing that. (4.0)
- AwakeFromLoad can be very expensive and stall the main thread.