So I’m making a bullet-hell shmup. Desktop is my primary platform, but I’m also planning to release it on iOS/Android so I’m building to those targets from time to time as I go. Right now, I’m experiencing a significant difference in performance on my iPad Mini (1st gen) vs. my iPhone 4. With tons of active bullets, I can sustain an easy 60 fps on the iPad, no problem. On the iPhone, the best I can manage is a very spiky 20-25.
The fact that the iPhone performs worse isn’t that big a surprise: the 4 is well-known to be an underpowered device (as opposed to the 4S, which is actually competitive), and the mini handily beats the 4’s hardware spec. So I’m not at all opposed to simply requiring a 4S or later; I’ve been doing a lot of profiling and optimizing, and I’m pretty sure the 4 is a lost cause. This isn’t a “help me make this game run on old iPhones” thread.
But I am curious to dig into which hardware differences are most “to blame” for the discrepancy.
The two major pain points on the phone are physics simulation, and scripts’ FixedUpdate calls. Together these average around 2ms/frame on the iPad and even less on desktop, but on the phone they’re anywhere from 7-20ms baseline, and if I get a perf spike the physics sim alone can easily exceed 100ms for a brief period.
So let’s talk about what’s going on in each of those places:
Physics sim: Obviously this is mostly a black box, but as far as what’s in the physics world, we’re looking at, on average, 100 or so rigid bodies (bullets and enemies), each with a single sphere collider marked as trigger (in fact everything is a trigger, because I don’t care about collision resolution in this game, only that a collision occurred at all). My fixed time step is set at 0.02 (50 Hz) and since everything’s a trigger, I turned the solver iteration count all the way down to 1. It’s worth noting that because most of the rigid bodies are bullets, that means I’m adding to and removing from the scene at a pretty good clip. I’ve written a stack-based object recycler so I’m not actually instantiating and destroying everything, but simply enabling and disabling instead. Nevertheless, profiling on the phone pops up “Dynamic Collider.Create” on enable (with a non-trivial amount of CPU time), whereas that doesn’t even show up on the iPad or desktop. ![]()
Script FixedUpdates: These are mainly the bullets, and certain weapons (responsible for spawning bullets… obviously) which need to fire rapidly enough that using a regular Update could introduce breaks in their bullet pattern. The bullets’ FixedUpdate is a single rigidbody.MovePosition call, with both the rigidbody and transform components cached. The only reason I even do this, instead of just applying an impulse at spawn-time and letting the physics sim handle the motion, is that I need to be able to scale the bullets’ velocities under certain circumstances depending on their team (if you’re at all familiar with Sine Mora, I’m more-or-less talking about its selective time-slow mechanic, here). The weapons do some logic, but its a minority portion of the overall FixedUpdate time, and not terribly worrisome.
From this page I compared the hardware specs of the iPad Mini and the iPhone 4. I highly doubt RAM or GPU are at issue here (unless Unity is running physics on some/all GPUs? Seems questionable on mobile in any case…) so I’m drawn to these two differences in particular:
- Processor: 1 GHz dual-core (iPad) vs. 800 MHz single-core (iPhone, underclocked from 1 GHz)
- Bus frequency: 250 MHz (iPad) vs. 100 MHz (iPhone)
Ultimately, what I’m wondering is whether this is more an issue of bus frequency (possible?), processor speed (questionable, with only a 200 MHz difference I wouldn’t expect the huge performance difference I’m seeing), or number of cores (seems most likely; can Unity run physics on a separate core if one is available?)
If I can get to the bottom of this, it’ll help me determine what other kinds of devices are likely/unlikely targets based on their hardware specs (i.e. if it’s a bus thing, then anything under a 250 MHz bus is probably on the no-go list, etc.)
Any thoughts?
P.S. If you’re a Unity dev and can answer some of these questions definitively, I’d love you forever and ever <3