Huge erratic slowdowns due to static batching

Hello everyone! I’ve been tearing my hair out over a really bizarre slowdown issue. I’m working on a big, complex game and I’ve had playtesters report low framerates on their PC, including from PC’s with modern GPU’s that really ought to be able to run the game well.

I’ve done some digging, and was able to consistently reproduce an issue on my laptop where the game randomly ran at 30fps, 60fps or 100fps whenever you pressed play. There was no visible difference between when the game runs well or when it runs poorly, it looks the same, and it has the same number of drawcalls too.


Profiler snapshot can be downloaded here

I’ve done a lot of testing and I’ve been able to create a minimal test case that seems to produce the same slowdowns:

  • Start a new 3D project (built-in renderer)
  • Make a lot of spheres (I made around 4,000 of them)
  • Set them all to static

Then when you run the game it will either run very well, or not. The framerate will stay at a seemingly random level. This can be seen both in the editor and in builds. The following seems to trigger the issue:

  • Reload the scene
  • Enable/disable the camera
  • Pause/unpause the editor

My project is currently using 2019.4.1f1 but I’ve also reproduced it with 2019.4.30f1.
UPDATE: I just tested it in 2020.3.18f1 (latest LTS release) and the problem is there, too.

It’s been a really difficult issue to track down because of its erratic nature. All I know so far is that if I don’t use static batching, the framerate is slower as you might expect, but it doesn’t go up and down erratically. So a workaround for me might be to use GPU Instancing instead of static batching for repeating objects like trees. However, I also have big complicated meshes for the level chunks which would presumably benefit a lot from static batching, so I’d prefer to understand what’s actually going wrong here.

Upon request I can produce a sample project that is more representative of my actual game, but that uses ~200 MB of custom assets so I chose to emulate the problem with built-in assets instead, which can be found here:

Repository with test case can be found here
.ZIP with test case can be found here

Any ideas as to what might be causing this? Or perhaps any best practices as to when immovable level objects shouldn’t be marked static?

I’d like to summon the almighty bgolus as 9/10 times when I’m reading a thread about some graphics issue he’s there providing some very well thought out and complete solution. I will do my best to earn his favor.


Oh almighty gods of optimization, grant me the wisdom of Bgolus the Wise in my time of need

I assume that’s the only way people get things done around here

My laptop reproduces the issue consistently and has the following specs:
GPU: Nvidia GeForce GTX 780M
CPU: Intel Core i7-4700HQ
RAM: 16GB

I’ve also tested it on a friends laptop (with a Nvidia GeForce GTX 1060) and couldn’t reproduce it there. I’m waiting for the playtesters that specifically reported the issue to try it out too.

Looking forward to your thoughts

2 Likes

Honestly to me this looks like wacky laptop power management shenanigans. I.E.: not anything you can do anything about as it’s being caused by something outside of Unity itself. You could use a hardware monitoring tool like HWiNFO64 to track the GPU’s clock rate and power draw (on laptops at least) and I suspect you’ll see each time you pause and start again it’ll lock to a different frequency. If your user is on a laptop like you are you might be able to fix the problem by adjusting the GPU’s power management mode in the GPU’s driver settings.

3 Likes

don’t mind me, just saving that last image for later… :wink:

2 Likes

Thanks bgolus! Very thoughtful and complete answer as per usual.

I tried having a look and it does indeed look like the GPU clock speed is fluctuating. Why it’s happening when I pause/unpause the game, enable/disable the camera, or why it didn’t happen when I disabled static batching, I don’t know. So far GPU throttling is the only answer that makes sense.

The biggest thing I’ve learned about this is that while grabbing an old laptop seems like a natural thing to do for testing your game on a low-end or mid-range device, but due to issues with temperature or power management you can get wildly inconsistent GPU clock speeds due to throttling, causing sporadic changes in framerate. That’s confusing and makes it not a very suitable test device. I’m going to profile on different devices instead.