Overhead spikes in the Unity3D profiler

I’m currently using Unity3D to build an iOS app and the other day I decided to do some profiling, just to make sure nothing is taking up crazy amounts of time. What I saw was pretty strange:

Now, if you Google the title of this post, you’ll find quite a few people who are seeing spikes in the Unity3D profiler for something called Overhead and if you follow those links you’ll find that for the most part people aren’t incredibly certain how to make them go away. The Unity3D docs don’t really explain what Overhead represents, but you can see it in the very first image on the page. Some people on the internet seem to think that Overhead includes garbage collection, but I’m pretty good about not creating tons of new objects every frame and others point out GC.Collect is what will show up for that. Also, if you look closely at the legend in the image you’ll see GarbageCollector has its own color.

No, it turned out that the culprit was using UnitySendMessage in a native plugin code! My app has a music system and in order to keep good metronomic time, I run the metronome with native code. This is important because if the metronome is only updated every frame, then you can wind up with wonky rhythm when there are framerate spikes. Lots of things are tied to the metronome in this app, so I needed a way to tell script about “ticks”, which simply means calling script on every sixteenth note. I used a line of code that looked like this:

This function tells the Unity runtime to find the object named “Metronome” in the scene and then call a function named “Broadcast” that takes a string. In my Metronome.cs script I then converted the string to a float and told all of the objects listening to the metronome that a tick just happened. I wrote it this way because the very first tip given for iOS plugins is “Managed-to-unmanaged calls are quite processor intensive on iOS. Try to avoid calling multiple native methods per frame.” So I figured having Metronome.cs call a native function every frame to retrieve ticks would probably be a bad idea, but it turns out it’s better than using UnitySendMessage.

I changed the way the metronome works so that when the native code gets to each tick it pushes it onto the back of a list, then in the Update function for my C# Metronome, I pass a float array to a native Metronome_GetTicks function, which then fills the array with all of the ticks in the tick list and returns how many ticks it put into the array. Then, for each tick in the array, I call the same Broadcast(float) method that I called from Broadcast(string). Now profiling the exact same level that gave me spikes looks like this:

2 thoughts on “Overhead spikes in the Unity3D profiler

  1. This is great! I’m interested in the overall design of your Metronome script — I’m working on a rhythm-based game myself and most of the solutions that I’ve found deal with step sequencer-esque apps. I’ve already made something similar to this (albeit much simpler) in AS3 with Flixel, but I’m having trouble figuring out how it would work in Unity.

  2. Basically, I run the Metronome in the audio thread. So an update function is called in the Metronome for every single audio sample that is generated by the app. By counting samples, I can determine when a Metronome “tick” is generated. In my case, I follow the MIDI standard of 24 ticks in a quarter note. This means that every 6 six ticks I push a value onto the script ticks list that indicates which sixteenth note in the measure just occurred. In script, I have a Metronome class that polls the code-side metronome every frame and sends out events to objects that have added themselves as listeners to the metronome. A class might want to do something every sixteenth note, or every quater note, or only on beat three.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">