7

I'm a pretty big newbie when it comes to optimization. In the current game I'm working on I've managed to optimize a function and shave about 0.5% of its CPU load and that's about as 'awesome' as I've been.

My situation is as follows: I've developed a physics heavy game in MonoTouch using an XNA wrapper library called ExEn and try as I might I've found it very hard to get the game to reach a playable framerate on an iPhone4 (don't even want to think about iPhone3GS at this point).

The performance degradation is almost certainly in the physics calculations, if I turn physics off the framerate jumps up sharply, if I disable everything, rendering, input, audio and just leave physics on performance hovers around 15fps during physics intensive situations.

I used Instruments to profile the performance and this is what I got: https://i.stack.imgur.com/Zmj8k.png The functions which drain the most performance are either from the physics engine (Farseer) or the ExEn XNA wrapper functions they call (notably Vector2.Max, Vector2.Min).

I looked into those functions and I know wherever it can Farseer is passing values by reference into those functions rather than by value so that's that covered (and it's literally the only way I can think of. The functions are very simple themselves basically amounting to such operations as

return new Vector2(Max(v1.x, v2.x), Max(v1.y, v2.y)) 

Basically I feel like I'm stuck and in my limited capacity and understanding of code optimizations I'm not sure what my options are or if I even have any options (maybe I should just curl into a fetal position and cry?). With LLVM turned on and built in release I'm getting maybe 15fps at best. I did manage to bring the game up to 30fps by lowering the physics precision but this makes many levels simply unplayable as bodies intersect one another and collapse in on themselves.

So my question is, is this a lost cause or is there anything I can do to beef up performance?

meds
  • 21,699
  • 37
  • 163
  • 314
  • I think you shouldn't be focusing on the library functions, but on your functions that call them. These functions are simple, which means you're calling them *a lot*. Look into the code and ask yourself: why am I calling them so often? Of course, the profiler should tell you on which parts *of your code* you should focus. – svick Jul 06 '11 at 14:22
  • The function calls come from the physics engine, the reason the calls happen so often is because every update cycle the physics engine needs to get the AABB boxes of all the bodies in the scene and check for intersections. The physics engine itself is very heavily optimized by people much smarter than I so I'm not sure what I could do on that front. – meds Jul 06 '11 at 14:26
  • Keep in mind that every time you create a "new Vector2", the GC will have to reclaim that at some point. It might be better to do an in-place replacement: "target.x = Max(v1.x, v2.x); target.y = Max(v1.y, v2.y);". – TreDubZedd Jul 06 '11 at 14:27
  • Do you think it could be a good idea to create a pool for the vector2s and then every update cycle release everything in the pool? – meds Jul 06 '11 at 14:36
  • Agree with TreDubZedd. I think you should start looking at in-lining some of the trouble spots. When you find a method call that is causing issues, replace it with inline code. So instead of calling Vector2.Max(), actually do the Max calculation yourself right where you would have made this call. And if you have to, modify the physics engine source code a bit. – Jeff Weber Jul 06 '11 at 14:49
  • 3
    Vector2 is a struct and should be handled by the stack, not the GC. If it is, then I would say mono isn't going to give you good performance with Farseer physics on mono no matter what you do. If mono is working correctly, Farseer should be running with zero allocations/deallocations as long as you don't add/remove bodies/geometry dynamically. – Jeremy Bell Jul 06 '11 at 15:04
  • 1
    Focus on the intersection detection. Especially if you have many bodys around you might need to find a local intersection routine (bodies which where far away from each other in one step ... are not really expected to overlap in the next, are they?). – FFox Jul 06 '11 at 16:04
  • +1 to Jeremy Bell's comment. `Vector2` is a value type (`struct`) and will *not* allocate memory (unless it is getting boxed as an `object` or one of its interfaces somewhere). – Andrew Russell Jul 06 '11 at 16:18
  • TIL. Thank you for the correction, @Andrew Russell and @Jeremy Bell. – TreDubZedd Jul 07 '11 at 16:27

2 Answers2

3

First of all, love your game on Windows Phone 7!

Secondly, I don't see anything out of the ordinary in your profiler output. I did a quick and dirty performance analysis of the Farseer engine once (running in .net) and came up with similar results. It almost looks like you have a slowdown that is proportional across the board and may be due to mono itself.

Jeremy Bell
  • 5,253
  • 5
  • 41
  • 63
  • Thanks for the feedback, and yes, my worst fears may be coming to light :D I just really wanted to make sure the performance appeared similar (i.e. there were no huge bottleknecks which could be avoided). But from what you're saying that is very unlikely. – meds Jul 07 '11 at 13:16
3

I suppose you follow the performance hints in http://farseerphysics.codeplex.com/documentation already :-)

  • The most important thing seems to be to reduce complexity for the collision detection calculations, i.e. not the visual but the colliding shapes. In Unijty3D they are called colliders and you can attach a simple cube as a collider to a complex human body. I don't know anything about Fareer but they probably have similar concept (is it called body?).

    If possible, try to replace your main character or other complex objects by easy cubes and check if fps raises.

  • Compiler switches sometimes leverage performance. Be really sure that there are no debug settings activated (I got up to 30 times slower code in a C++ library project). Ensure that armv7 optimisation is turned on and -O3 or -Os

  • Watch out for logging statements as they are extremely expensive on iPhone

[Update:]

  • Try to decrease the number of actively calculated AABBs just to find out which part of the physics engine causes the trouble. If it's the pure number follow FFox' advice.

  • What is about other platforms? Where did you perform the testing during the development phase, on simulator? Which one? Any chance to get it running on Android or Android simulator or Windows Phone? This would give you a hint if it is an iPhone specific problem.

  • Ah, I just saw that ExEn still is in pre-release state and the final will be launched on July 21th as OS. IMO this changes the situation: If your App is running fine on some other comparable platform, then just wait for the release and give it a new try. Chances are pretty well that there is still debugging code in the pre-release you are working on.

Community
  • 1
  • 1
Kay
  • 12,918
  • 4
  • 55
  • 77
  • Yep, I'm sad to say I've looked into everything you've mentioned and I'm still finding the performance to be lacking :( Thanks for the answer none the less! – meds Jul 07 '11 at 13:17
  • I feel really sorry for you. When I did this library thing I spent days of frustration. But we don't want to give up:) I have updated the answer – Kay Jul 07 '11 at 21:11
  • 1
    @Kay: (background: I wrote ExEn) - Actually the maths types in ExEn already are up to release standard, with no debugging code. I haven't and don't really plan to profile and squeeze out every last cycle - but they certainly shouldn't be "slow". There's not much to them. (I've also wrestled with the same physics issues on iOS - getting physics running on the tiny iPhone CPU is a pain. The best I could do was to significantly reduce the number of points of contact in my scenes.) – Andrew Russell Jul 08 '11 at 04:15
  • @Andrew: Cool project:) Related to meds problems: Do you know anything about comparing the same code's performance on Windows Phone 7 and iPhone? – Kay Jul 08 '11 at 08:29
  • @Kay I'm afraid not. It would be interesting to know how Mono + iPhone hold up, though. I do work under the assumption that the MonoTouch compiler is of reasonably good quality. – Andrew Russell Jul 08 '11 at 14:28