godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.89k stars 21.03k forks source link

2D Physics performance issue #600

Closed marynate closed 5 years ago

marynate commented 10 years ago

How to reproduce:

  1. In 2D Platformer project, open bullet.xml
  2. Select "Timer" node, change Wait Time to longer period, e.g. 300
  3. Publish game to mobile device, shooting bullets

In iPad2: 0 bullets - 60fps 10 bullets - 54 20 bullets - 30 fps 30 bullets - 20 40 bullets - 20 50 bullets - 15

Found one blog post doing physics benchmark on iPad1 in 2011 (http://tech.flyclops.com/battle-of-the-ios-physics-engines-197), here's the their result of box2d on iPad 1:

200 rigidbody 60fps
370 rigidbody 30fps
406 rigidbody 15fps
marynate commented 10 years ago

bullet in 2d platformer example is more complex than a simple rigidbody, for more fair comparison, I use testcase posted here (https://github.com/okamstudio/godot/issues/515) and here's the result on my iPad2:

100 rigidbody 60fps
200 rigidbody 30fps
400 rigidbody 3fps

Still, it's much slower comparing to box2d even on iPad 1.

Maybe it's worth to consider integrating box2d in godot for 2d physics?

reduz commented 10 years ago

Try changing "cell size" in physics_2d from 128 to 32 and you will definitely notice a performance boost. Also keep in mind the game is processing an entire particle system for each bullet too.

On Tue, Jul 22, 2014 at 1:45 AM, marynate notifications@github.com wrote:

bullet in 2d platformer example is more complex than a simple rigidbody, for more fair comparison, I use testcase posted here (#515 https://github.com/okamstudio/godot/issues/515) and here's the result on my iPad2:

100 rigidbody 60fps 200 rigidbody 30fps 400 rigidbody 3fps

— Reply to this email directly or view it on GitHub https://github.com/okamstudio/godot/issues/600#issuecomment-49697787.

godotengine commented 10 years ago

also keep in mind each bullet is doing a round-trip through the scene system and moving a few nodes. If you have a real world use case where you want loads of rigid bodies you should aswell ignore the scene system and using nodes and go for the Physics2DServer/VisualServer APIs directly.,

On Tue, Jul 22, 2014 at 2:08 AM, reduz notifications@github.com wrote:

Try changing "cell size" in physics_2d from 128 to 32 and you will definitely notice a performance boost. Also keep in mind the game is processing an entire particle system for each bullet too.

On Tue, Jul 22, 2014 at 1:45 AM, marynate notifications@github.com wrote:

bullet in 2d platformer example is more complex than a simple rigidbody, for more fair comparison, I use testcase posted here (#515 https://github.com/okamstudio/godot/issues/515) and here's the result on my iPad2:

100 rigidbody 60fps 200 rigidbody 30fps 400 rigidbody 3fps

— Reply to this email directly or view it on GitHub https://github.com/okamstudio/godot/issues/600#issuecomment-49697787.

— Reply to this email directly or view it on GitHub https://github.com/okamstudio/godot/issues/600#issuecomment-49698848.

OkamStudio

marynate commented 10 years ago

thanks reduz. I tried changing "cell size" to 32, but did not notice any difference in fps.

btw, I take code from "Speed comparison: 2d Unity vs Monkey" (http://forum.unity3d.com/threads/speed-comparison-2d-unity-vs-monkey.248926/) convert it to godot. In unity, it's 2000 gameobjects, and in godot, it's 2000 sprite node. Here's the result:

desoptop: godot: 124 fps unity: 300 fps

iPad 2: godot 12 fps unity: 20 fps

since there's no physics involved in this test, not quite sure what might the reason that there's such fps different

reduz commented 10 years ago

That's not too bad considering there was never any real attempt to do any optimization so far. You could try running the godot test with: valgrind --tool=callgrind godot and see where the hotspots happen

rraallvv commented 9 years ago

Just out of curiosity, does Godot use SIMD instructions in the physics engine, and/or vector and matrix algebra. If not what about using libraries like eigen or kazmath?

reduz commented 9 years ago

it's not using SIMD anywhere. Converting the maht classes to simd compatible (so the autovectorizer can optimize them) is a pending task. Before doing heavy optimizations, having some benchmark tests would be desired, so those need to be created first, to have as reference.

On Sun, Dec 21, 2014 at 8:34 PM, rraallvv notifications@github.com wrote:

Just out of curiosity, does Godot use SIMD instructions in the physics engine, and/or vector and matrix algebra. If not what about using libraries like eigen or kazmath?

— Reply to this email directly or view it on GitHub https://github.com/okamstudio/godot/issues/600#issuecomment-67787920.

rraallvv commented 9 years ago

I see, I'd be happy to help with those benchmark tests.

reduz commented 9 years ago

i tested this a bit, and the main reason of the performance hit according to callgrind is that 2D math functions in Godot are not inlined. so project_range() and solve() (that use vector math a lot) are really slow.
From the few things i saw in the callgraph, there really are many issues to optimize, but I would really rather a set of benchmarks is properly done and put together before this

I haven't worked on this much because the goal would probably be to modify the vector math classes to be more SIMD compatible, like Bullet does, but this hasn't happened yet.

If anyone wants to help put together a few benchmarks, so a good frame of reference for optimization can be obtained, then it's very welcome.

reduz commented 9 years ago

I want to add that I'm not that experienced in SIMD optimization using autovectorization. I know that technically if your code emulates the way simd works, the autovectorizer will do it's job but my lack of experience with SIMD assembler (both SSE and NEON) would make it difficult to test if the compiler is optimizing properly.

rraallvv commented 9 years ago

I'would like to start making some tests with SIMD, pretty much it would be just copy-paste-ing the assembler code used for all the vectors and matrix algebra from other physics engines, mostly bullet physics. Godot already does almost all the memory allocations aligned, so it would be rather easy to just add the vectorization part.

I started making some research on how to do those optimizations relying on the compiler to do its thing, but no luck, there should be a reason why nobody rely on the compiler to do those things, not even for copying memory.

This is the scene I'm using to do the profiling and testing.

output

For instance that very same scene created "by hand" with bullet physics and GLKit, runs at 60 fps on an iPod Touch 5G, using NEON, here is the repo if anyone wants to give it a try. Godot runs the same scene at 4~6 FPS. That's the reason why I'm eager to start doing optimizations.

Also I had to hack the classes Vector and DVector, because they reserve the first bytes for the ref counting and elements size, therefore misaligning the data. The class Variant has its data misaligned too, so I had to allocate the data dynamically.

I will post the PR if anyone wants to do some tests.

Update

Please note that the results googling by "Compiler Vectorization" show a bunch of papers, and peer-reviews, no tutorials, nor examples, and the first stackoverflow question that pops out is "Intel compiler cannot vectorize this simple loop?", with an answer that seems like an alchemy recipe for me.

akien-mga commented 6 years ago

First of all thank you for your report and sorry for the delay.

We released Godot 3.0 in January 2018 after 18 months of work, fixing many old issues either directly, or by obsoleting/replacing the features they were referring to.

We still have hundreds of issues whose relevance/reproducibility needs to be checked against the current stable version, and that's where you can help us. Could you check if the issue that you described initially is still relevant/reproducible in Godot 3.0 or any newer version, and comment about it here?

For bug reports, please also make sure that the issue contains detailed steps to reproduce the bug and, if possible, a zipped project that can be used to reproduce it right away. This greatly speeds up debugging and bugfixing tasks for our contributors.

Our Bugsquad will review this issue more in-depth in 15 days, and potentially close it if its relevance could not be confirmed.

Thanks in advance.

Note: This message is being copy-pasted to many "stale" issues (90+ days without activity). It might happen that it is not meaningful for this specific issue or appears oblivious of the issue's context, if so please comment to notify the Bugsquad about it.

akien-mga commented 5 years ago

As there was no answer to the above request, we're closing this issue as inactive. If you can still reproduce it, please open a new issue against a currently supported release of Godot.