Huge performance difference between Ipad1 and Iphone4?

While optimizing our project I frequently ran into problems with low framerates on the iphone4, both on iOS 4.3 and iOS5. However when I built the same project to an Ipad 1 I saw a huge performance increase. On the iphone4 devices I frequently got as low as 22-23 fps when a lot of stuff is happening on the screen. On the ipad1 I had problems getting it to drop to 35, usually staying 38+.

I’ve copied a series of results from the internal profiler on both an Iphone4 iOS5 (also tried Iphone 4 with iOS4.3, but the results were pretty much identical) and on an Ipad1 with iOS4.2.

The “simple scene” is the start of the level in my project, should be identical on both devices. A skinned character idling in an environment with a shadowblob and a charactercontroller, a lightmapped scene with few elements. The viewport is top-down so viewdistance is not really factoring into differences between the two scenes.

In the “heavy scene” I´ve run along and pulled some enemies to me. It has an additive transparent lightbeam taking up a lot of screenspace. Three additional characters with pathfinding, some more scene objects on screen, and I’m trying to collide and mess around with them as much as possible. These scenes are not identical. But over time the Ipad1 kept to around 37-38fps, while the iphone4 ranged from 22-28fps in the heavy part.

Wondering if someone knows any reason I should be seeing this huge a difference. Afaik the ipad1 and iphone4 has the same CPU, but the ipad1 has less memory and more screen real-estate to draw. So I’m surprised at the results. On an Ipad2 it runs at a steady 60fps all over(yey!) And I’m going to test on an Ipad1 with iOS5 over the weekend.

Here are the results, hoping someone spots something crucial so I get consistent performance on both devices.
It’s the exact same project built to both devices, just swapped cables and rebuilt.

Built with XCode 4.2

IPAD1 iOS 4.2.1 build target iOS 4.2

Simple part of level 60fps

iPhone Unity internal profiler stats:
cpu-player> min: 12.5 max: 15.9 avg: 13.9
cpu-ogles-drv> min: 0.7 max: 2.4 avg: 0.8
cpu-waits-gpu> min: 1.3 max: 10.6 avg: 5.7
msaa-resolve> min: 0.0 max: 0.0 avg: 0.0
frametime> min: 15.0 max: 18.8 avg: 16.7
draw-call #> min: 12 max: 13 avg: 12 | batched: 35
tris #> min: 2399 max: 2407 avg: 2402 | batched: 2970
verts #> min: 2220 max: 2236 avg: 2227 | batched: 1387
player-detail> physx: 2.7 animation: 0.2 culling 0.0 skinning: 0.3 batching: 0.1 render: 2.3 fixed-update-count: 0 .. 1
mono-scripts> update: 1.3 fixedUpdate: 0.2 coroutines: 0.0
mono-memory> used heap: 1245184 allocated heap: 1617920 max number of collections: 0 collection total duration: 0.0

Heavy part of level ca. 38fps

iPhone Unity internal profiler stats:
cpu-player> min: 19.1 max: 24.0 avg: 21.2
cpu-ogles-drv> min: 1.3 max: 3.9 avg: 1.5
frametime> min: 24.1 max: 30.9 avg: 26.3
draw-call #> min: 27 max: 29 avg: 27 | batched: 61
tris #> min: 5866 max: 6174 avg: 6104 | batched: 4489
verts #> min: 5076 max: 5403 avg: 5320 | batched: 2282
player-detail> physx: 4.9 animation: 0.6 culling 0.0 skinning: 0.9 batching: 0.1 render: 8.1 fixed-update-count: 0 .. 1
mono-scripts> update: 3.7 fixedUpdate: 1.1 coroutines: 0.1
mono-memory> used heap: 1626112 allocated heap: 2158592 max number of collections: 0 collection total duration: 0.0

Iphone4 iOS 4.3.5 build target iOS 4.3

simple part of level ca. 48fps

iPhone Unity internal profiler stats:
cpu-player> min: 9.7 max: 21.7 avg: 15.8
cpu-ogles-drv> min: 1.0 max: 3.1 avg: 1.5
frametime> min: 13.4 max: 27.0 avg: 20.6
draw-call #> min: 13 max: 14 avg: 13 | batched: 38
tris #> min: 2435 max: 2443 avg: 2439 | batched: 3024
verts #> min: 2271 max: 2287 avg: 2279 | batched: 1414
player-detail> physx: 5.1 animation: 0.2 culling 0.0 skinning: 0.4 batching: 0.2 render: 4.1 fixed-update-count: 0 .. 1
mono-scripts> update: 2.3 fixedUpdate: 0.3 coroutines: 0.0
mono-memory> used heap: 1798144 allocated heap: 2154496 max number of collections: 0 collection total duration: 0.0

heavy part of level ca. 25fps

iPhone Unity internal profiler stats:
cpu-player> min: 24.7 max: 33.4 avg: 28.1
cpu-ogles-drv> min: 1.8 max: 4.3 avg: 2.5
frametime> min: 31.6 max: 44.0 avg: 37.0
draw-call #> min: 24 max: 28 avg: 26 | batched: 69
tris #> min: 6156 max: 6770 avg: 6375 | batched: 5140
verts #> min: 5347 max: 6017 avg: 5609 | batched: 2608
player-detail> physx: 9.7 animation: 0.9 culling 0.0 skinning: 1.1 batching: 0.1 render: 5.0 fixed-update-count: 1 .. 2
mono-scripts> update: 5.6 fixedUpdate: 1.9 coroutines: 0.1
mono-memory> used heap: 1859584 allocated heap: 2154496 max number of collections: 0 collection total duration: 0.0

looks fine, the performance delta comes from the cpu limitations you are hitting (the frametime ie rendering is the same), which is a consequence of the iphone 4 cpu being 20% slower than the ipad1 (same chip but downclocked to 800mhz from 1000mhz), as such you will need to work on the cpu usage, and optimize your scripts. Likely you are doing path finding on a pretty heafty level for mobiles, be it too long paths, too detailed grids, too far ranges or too complex nav mesh (alternatively you use getcomponent and alike all the time instead of caching)

Downclocked aha! That’s very helpful, thanks!

I was working mostly with the unity active profiler, and focusing on getting rendertimes down since they seemed to be 50%+ of each frame. The scripts seemed to spend maybe half of that, and physics the rest. I guess it’s time to go back to the scripts then.

ensure to connect the profiler to the device and to interpret the right percentages (not the self ones) that should get ya going.

In above examples you can look at render+cpu-ogles-drv vs cpu-player basically. you are right that physics is quite a bit high, you have 10ms in there, and 6ms in your Updates, 2ms in FixedUpdate. these 3 on their own without any rendering already make 60fps impossible for example

Not sure which results to go by here. The active profiler shows the render to be consistently around 50% of the frametime in the heavy areas, being around 10-14ms. The scripts are around 25% and the physics 15%.

I don’t think the pathfinder is costing much, everything should be cached, the pathcalls are on intervals and distributed so they don’t all call paths at the same frame. And due to the way they’re activated they won’t start pathing until the character is max 10’ish gridspaces way. The pathfinding routines I can find in the profiler also just show up as thin pixelstripes of the full graph.

That last profiler test was on the iphone. On the ipad, the render functions on average go up by maybe 10% of the frametime.
I guess that would make sense if the CPU on the ipad is faster and the cpu intensive workload drops in the frametime percentages?

Not exactly sure what the architecture is like in these devices though, is the cpu and the gpu completely separate?

In any case we’re aiming for capping it to 30fps, as long as I get it consistently above that, by just a frame, I’m happy. The 3GS ran the same scenes at around 28fps, dropping to 20fps in the more messy moments. We’ll see what we can do about turning off misc. niceness to get the fps back up at the lower end.

turning off misc niceness isn’t going to help if you mean visuals. The 3gs is faster at rendering than both the ipad and 4g… Dreamora is right, it is script optimisation you need to look into.

Yeah cpu and gpu is seperate.
I reformulated above to be more accurate.
At the time you hit on both sides close to the limits, rendering and cpu. But the rendering is about the same on both so the additionally lower performance on iphone4 is a consequence of cpu overload.

That it runs that fast on the 3GS is funny. do you have some scaling code that reduced the cpu work load there?
cause the 3GS cpu is another 30% or so slower than on the iphone4 already (its not the same cpu, its an older, less capable one, running at 600mhz) so the cpu time should likely exceed the 33ms with that physics heavy aspects.

Normally when the 3GS runs faster than iphone4 or ipad, its related to graphics caps, more precisely the fillrate (too much overdraw on the screen ie big transparent objects). Its even more interesting that in such a scenario the ipad should exceed the iphone4 cause the ipad has worse problems on the fillrate than the iphone4 (both have the same GPU as the 3GS, just so you understand the whole prob on why the 3GS wins when its graphically capped :))

Ok this is very interesting, so basically I should be getting about the same time spent in render ms on all three devices. And see the most impact happening in the physics and scripts department?

The 3GS didn’t win out though(but I might have misunderstood your meaning), my numbers turned out something like this:
Ipad2 60-60fps
Ipad1 60-38fps
Iphone4 45-25fps
3GS 28-20fps

I guess it makes sense to see the biggest differences and drops in the devices with the highest fps.

I see what you mean, I feel like I’m not getting the whole picture from the active profiler, since the render usually comes out as the biggest chunk of ms, when just testing scenarios vs. FPS seem to point in other directions. All the devices are fine when there’s not much more than rendering going on.

I’m definitely going to have a look at the physics aspect, I’m getting higher fps running away from the enemies and giving them longer paths, than if I bunch up with them and collide, stopping their pathfinding and giving physics a lot to do. Just standing still in the middle of them brings the fps up to the top end of whatever device it’s running on. Nice to see the iphone 3GS running at 30fps in that scenario, even though that makes it a lot harder than “lets turn off dropshadows for the 3gs then!” :slight_smile:

Good news!

  1. Switched the charactercontrollers into a “sliding collider” solution I made as a backup, as the precision between enemies and character isn’t that important. He still feels appropriately hampered by them.
  2. Due to a badly timed update from the asset server. A lot of the level I used to test had gotten double colliders. This probably worked as a multiplier of any cost on the characters.

The iphone4 now usually floors at 31-32 fps, instead of 25 as before. The 3GS actually reaches for the 40s in the low cost scenarios, while dropping to about 28, or worst case 25 when jumping into a group of enemies.

As we’re able to be flexible on encounter sizes and pacing of enemies, things are looking up!

Thanks for steering me away from the rendering guys!

From a little experience a while ago, maybe it can be useful to solve your problem.

I was stress testing for a game with the goal to hit constant 60fps on 3gs+ device, to learn where the limits were for the single platforms (iPad1, iPhone 4, 3GS). It’s a sidescroller shooter, with lots of moving objects, colliders and physics (around 100+ physics object moving and colliding). Avoiding overdraw and with some tweaking everything was smooth on every platform, but I had some nasty performance spike on the 3GS after adding a couple of objects that caused no problem on the other platforms. The problem was with a single sphere collider that didn’t have a rigidbody attached and was moving, causing PhysX to recompute the collision array for static colliders internally every frame: that posed no visibile problem on the 4 and iPad, but on the weaker 3GS CPU it was enough to lose around 10-15fps.
Added the rigidbody to the object and everything was fine again. :wink:
Physics can hit a lot harder on 3GS…

PS: sorry for the bad english, I’m italian. :wink:

If only native English speakers’ English was that “bad.” :wink:

–Eric

That’s interesting. My enemies use a box collider without any rigidbodies, but they’re not tagged as static. They’re set to not collide with anything but the player. The player is stopped by them consistently when they’re standing still and sometimes pushes through when they’re moving, which is ok for our purposes. In my experience having rigidbodies and a bit sloppy collision makes them suddenly find themselves inside another collider and shoot off with a huge force.

So I guess I’m wondering, does unity consider all non-trigger colliders without rigidbodies to be static, even when they’re not tagged as static?

static has nothing to do with physics. static is only used for static batching, umbra and beast.

for physics, yes anything without a rigidbody is nonmoving physically basically. (if you move it none hte less it will not do so physically but teleporty)

if the 3gs is faster, it means rendering is the bottleneck.
if the 3gs is slower, it means the cpu is the bottleneck.

Simple rules that work.

If you move any colliders without a rigid body, physx will be slow, as it will try and internally optimise it. For moving colliders (only), add a rigid body and enable trigger + isKinematic.

Thanks for the tips. I saw references to “static colliders” in the profiler. Assumed they meant colliders with the static tag. I’ll make the changes and see what happens. “isTrigger” though, doesn’t that disable collisions? As in it collides and registers stuff, but doesn’t actually stop any objects or apply forces?

I’d love to know more about how to interpret the profiler,

The graph window states “CPU”, I guess it mean both gpu and cpu?

The profiler seemingly adds together the ms cost of script, render, physics etc. for each frame, giving you an estimated framerate. If these miliseconds are “spent” on two seperate gpu/cpus, how does adding them together make sense? I assume the processors have a more complex method for dividing work than “both at the same time” or “one after the other”, but it would be nice to know how to better read the numbers. For example seeing that physics is 25% of your frametime might really mean that physics has 0% impact on your frametime If it’s actually bound by the gpu. Or?

LOL, thank you. :slight_smile:

BTW, got Vectrosity months ago, amazing work. :wink: