Genesis icon indicating copy to clipboard operation
Genesis copied to clipboard

Performance test: Low FPS with 20 cubes in fluid simulation and 100 cubes in free fall

Open oneanime opened this issue 10 months ago • 7 comments

Thank you for your amazing work on this project! I’ve been testing the simulation, but I’ve encountered some performance issues, and I’d like to ask for your advice.

Here’s my setup:

GPU: NVIDIA RTX 3080 Scenario 1: When I place 20 cubes into a fluid simulation, the frame rate drops below 1 FPS. Scenario 2: When I simulate 100 cubes in free fall, the frame rate is below 10 FPS. For comparison, I’ve tested a similar scenario in PhysX:

130 convex polyhedra in fluid simulation run smoothly. 100 cubes in free fall also perform well. I’m curious: why is PhysX performing faster in these tests? Are there specific optimizations or differences in the implementation that might explain this?

Is there anything I can adjust in my setup to improve performance in your simulation?

Thank you in advance for your help!

oneanime avatar Dec 31 '24 06:12 oneanime

In our project, there are many rigid bodies colliding with each other. We want to know whether Genesis is faster than PhysX, but this simple test did not show any speed advantage for Genesis.

oneanime avatar Dec 31 '24 06:12 oneanime

The main difference is genesis follows mujocos constraint formulation and uses a global solvers to solve everything until the whole scene converges, and physx uses local solvers. (Hence it’s less sphysiy accurate) This means the system complexity in Genesis is quadratic w.r.t number of dof, while physx is linear

if the cubes are in contact with the floor , you can turn on contact island Greatly speed up contact resolving to a linear level. Also if you are not doing parallel simulation and there’s no fluid, you should use cpu back end

one more thing — how big is the fluid bock you use? The default particle density could be very expensive. If would be good if you share your script. Phsx uses PBD fluid which is computationally lighter than SpH solver we used, and is also less accurate

zhouxian avatar Dec 31 '24 07:12 zhouxian

I modified the quantities in the sph_rigid.py example for testing purposes. When testing free fall, I commented out the part of the script where fluid is added.

import argparse

import genesis as gs


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("-v", "--vis", action="store_true", default=False)
    args = parser.parse_args()

    ########################## init ##########################
    gs.init(seed=0, precision="32", logging_level="debug",backend=gs.gpu)

    ########################## create a scene ##########################

    scene = gs.Scene(
        sim_options=gs.options.SimOptions(
            dt=1e-2,
            substeps=100,
        ),
        sph_options=gs.options.SPHOptions(
            lower_bound=(0.0, -1.0, 0.0),
            upper_bound=(1.0, 1.0, 2.4),
        ),
        vis_options=gs.options.VisOptions(
            visualize_sph_boundary=True,
        ),
        viewer_options=gs.options.ViewerOptions(
            camera_pos=(3.5, -3.15, 2.42),
            camera_lookat=(0.5, 0.0, 0.5),
            camera_fov=40,
            max_FPS=60,
        ),
        show_viewer=True,
    )

    ########################## entities ##########################
    frictionless_rigid = gs.materials.Rigid(needs_coup=True, coup_friction=0.0)
    plane = scene.add_entity(
        morph=gs.morphs.Plane(),
    )
    # water = scene.add_entity(
    #     material=gs.materials.SPH.Liquid(mu=0.01, sampler="regular"),
    #     morph=gs.morphs.Box(
    #         pos=(0.5, 0.0, 0.6),
    #         size=(0.9, 1.6, 1.2),
    #     ),
    #     surface=gs.surfaces.Default(
    #         color=(0.5, 0.7, 0.9, 1.0),
    #     ),
    # )


    cube_list=list()
    for i in range(100):
        cube = scene.add_entity(
            material=frictionless_rigid,
            morph=gs.morphs.Box(
                pos=(0.5, 0.0, 2.4+i*0.2),
                size=(0.2, 0.2, 0.2),
                euler=(30, 40, 0),
                fixed=False,
            ),
        )
        cube_list.append(cube)










    ########################## build ##########################
    scene.build()

    for i in range(500):
        scene.step()


if __name__ == "__main__":
    main()



oneanime avatar Dec 31 '24 07:12 oneanime

One thing I immediately noticed is that — substep is 100, so the effective FPF is actually 100x bigger

could you also share your physx testing script? Free fall shouldn’t be that slow

@YilingQiao could you look more into this?

zhouxian avatar Dec 31 '24 07:12 zhouxian

I apologize for this. The substep is set to 10 by default when I was conducting the test. The PhysX test case was written using the C++ PhysX SDK, but it needs to be organized before I can provide it. However, I can describe the scenario: in a pool of water, many 20-sided prisms are placed, allowing these objects to collide with each other. The dimensions of the pool are 30x50x5 (length, width, height). The distance between particles is 0.1f, the density is 1000.f, and the total number of particles is calculated by multiplying the pool's length, width, and height.

oneanime avatar Dec 31 '24 07:12 oneanime

and how many particles are there and in genesis?

zhouxian avatar Dec 31 '24 14:12 zhouxian

We might revisit the fluid simulation and comparison with physx later

YilingQiao avatar May 24 '25 17:05 YilingQiao