Profilers: An Underused Asset
When my team comes across problems in performance, or even a crash occurs in our games, the first question I ask is, “Did you check the profiler?” I am shocked by how little developers don’t even know what a profiler is. So here is a general rundown.
The profiler is basically a report for your game. It shows how much time your code takes, how much memory you are using, etc. It is there to help optimize your game when you are wondering why your game runs at 6 fps (yes, I had to deal with that at some point with no fault of my own). The profiler itself has a bit of overhead to it, but not terribly significant. Xcode has a profiler, Unity3D has one, Unreal has one; it is quite a common tool that every programmer AND DESIGNER needs to know how to use. I say every designer because the most common thing I hear is “Oh, our game is a bit laggy”. That is not helpful, and sometimes, it’s not even the programmer’s fault on why it runs a bit sluggish. I’ll give you an example later, but let’s teach you how to use the profiler.
Using the profiler
For this, I am going to be talking about Unity3D’s profiler, because that’s the one I have the most experience using. To pull it up, just right click on any tab you have open and Add tab->Profiler. You can check out Unity’s documentation and it goes more in-depth than what I am about to do. So, here is what the profiler generally looks like.
DISCLAIMER: I’ve either created or modded existing project’s code for these profiler screenshots, so I don’t want to hear anyone complain about the performance on some of these screenshots. It’s meant to look bad, and it is not what is implemented.
Each little section is important in its own way, and if you click on it, it will give you more details in that section. The CPU section basically tells you where your game spends it’s time, whether it is physics, scripts, rendering, etc. This part is where you will likely look when your program gets sluggish. But, if your CPU tells you it is spending most of its time on drawing, you might want to take a look at the GPU section and the Rendering section. The Memory section is important if you are doing mobile (I’ll explain later) or if you have a strict memory limit. The Audio and Physics sections is self explanatory, so I am not going to go into them. Depending on your particular game and platform, you may need to keep an eye on a certain portion more than others.
I’m going to give a few scenarios on what could be wrong. It’s a little game called:
“WHOSE FAULT IS IT?”
Here is a clip of the profiler for the first scenario. This is a little (actually it’s a lot) made up, but its going to show the idea.
So, whose fault is it? Programmers, it’s your fault, and you should know better. Usually, the script portion problems aren’t as obvious as this, but I thought that I would make this one easy. Usually, you have to deal with the consequences of your scripts; Instantiation, making something all alpha, stuff like that. It will never be this easy, so know how your scripts will affect the profiler. If you are doing 20,000 raycasts in an update, you should rethink your choices.
This is the profiler screenshot when I had to deal with the 6fps incident (I obviously cleaned it up, but I messed it up a bit for the sake of this post). This happened in the game project I was a part of, Iris (some of the parts don’t show because this was before Unity 3.5).
So, whose fault is it? Programmers, you can take deep a breath. The designers messed up on this one. When it’s the CPU usage is mostly physics and the programmers aren’t doing much with it nor doing instantiation calls, it’s because some designer got a bit click happy and decided to place near 800 rigidbodies in a scene all doing physics calculations at the same time. If you are confused, look at the bottom of the picture and you can see my point. At this point, the designers need to relax and rethink their decisions. Sure, it would have been a cool puzzle, but if the game doesn’t run fast, all you have is a picture.
Now this one is going to be tricky. This is the profiler during SpartanVilla when it would crash.
So, whose fault is it? Surprise! It is everyone’s fault. And here is why. No one really understood some of the limitations of mobile devices, the big one being texture memory. Speaking of which…
Profiler for mobile devices
Since there are more limitations on a mobile device than there are for desktop, there are some key things you need to keep an eye on. Texture memory is going to be your enemy, and once you break the threshold, your game will crash. For Unity, it’s the blue line that will be your problem.
Obviously this threshold is all dependent on what device you are running, but here is a general rule of thumb: no more than 25MB for texture memory. It helps to keep it below that if you can help it, but anything above that you should treat that as forbidden. S0, I’m going to give you some helpful tips on making sure that your texture memory will not be a pain in your side (TELL YOUR ARTIST! IT’S ON THEM TO HELP OPTIMIZE!):
- Make atlases instead of individual sprites. It is much better on performance to load in 1 texture and choose a section of it instead of loading from multiple sprites. That’s why 2D sprite sheets are on 1 texture and not a whole bunch of little separate poses.
- Structure your atlases so UI elements all relate to each other. If you are showing a menu and all the elements are coming from the same atlas, you have done something right.
- Have textures larger than 1024×1024 (including atlases). Anything bigger than that will cause you headaches down the road. If you are targeting older devices, no bigger than 512×512. If you have structured your atlases correctly, you won’t run into this problem.
- Have multiple atlases loaded. Sometimes this is a bit unavoidable, but this goes back to structure. The better you structure, the less images you have to pull and show.
Things to keep an eye on
I didn’t stress this earlier, but it is actually very important. Keep an eye on the GPU usage. Transparent calculations are much more expensive than opaque and I’m sure any graphics programmer would love to give you a chat if you don’t watch it closely.
Another thing to keep an eye on is the Rendering section. It will tell you how many draw calls the game is doing, and will likely be the reason why the game is running slow on certain parts of the game and not others.
Also, you should look at the percentages more closely than the graph. The graph will adjust automatically based on fps. So if the graph is mostly your scripts, but it runs at 1000fps, no need to sweat bullets.
Small exercises you can do
Make really bad test scripts , and see what happens to the profiler. After you have done that, improve upon your scripts and notice the difference in the profiler. Here are some things you can do when you are making these scripts:
- Long and intense calculations on single objects (do it on Update to make things worse)
- Mess with the transparency with multiple objects
- Do a simple function, but on multiple objects
Another thing you can do is mess with what the engine already gives you. You like cubes? Put 1000 in a scene with some rigidbodies and look at the profiler. Really like cubes? Put in a lot of lights to show off their faces (I know some programmers out there just cringed. I’m sorry).
Once you know the impact of what each scenario does, you will keep that in mind when implementing your future games. That way, you can keep an eye out for some sketchy stuff people try to pull without needing to look at the profiler. For designers, make sure you run your changes through and check what performance impact it has.