rapier icon indicating copy to clipboard operation
rapier copied to clipboard

Async support

Open devnought opened this issue 3 years ago • 9 comments

I'm opening this issue to get a discussion on async support in rapier, namely, does it even make sense?

Without looking at the design of rapier, I don't believe there's too much opportunity for work-stealing when computing the physics simulation, and if that's the case async might not make much sense.

The only thing that comes to mind is sharing a thread pool in a project that already has an asynchronous executor defined (i.e. tokio, smol, async-std). If your project is performing concurrent operations, and some of your dependencies are all trying to spawn threads to do their own work, maybe it could be beneficial if they all shared the same thread pool.

But again, maybe this doesn't make sense and doesn't warrant the effort! I at least want to have the conversation and see what folks have to say.

devnought avatar Aug 26 '20 13:08 devnought

Currently parallelism is done with Rayon. Can this be mixed with async easily?

One difficulty with supporting async is that I guess this would require modifying most code to use the async/await syntax. It would be great if we could think of an easy, quick way to determine whether or not using async will be beneficial performance-wise.

sebcrozet avatar Aug 28 '20 07:08 sebcrozet

Currently parallelism is done with Rayon. Can this be mixed with async easily?

I'm not sure how easily this can be accomplished. I'm going to finally pull down rapier and take a look at the overall architecture and get back to you.

To your point about performance, to see if there was any benefit, it's pretty much going to be an all-or-nothing, but I'm willing to take a stab at it to at least figure out if it's worth perusing further in the future.

Not physics related, but the bevy project indicated in their most recent blog post that they measured some considerable performance wins by moving from rayon to a custom async task system.

devnought avatar Sep 22 '20 00:09 devnought

FWIW: I personally would rather keep the rapier api synchronous, as it would force users to run their physics asynchronously. If the user api would be unaffected and there are performance gains then I would consider internal async to be a win.

Bombfuse avatar Jan 01 '21 23:01 Bombfuse

Not physics related, but the bevy project indicated in their most recent blog post that they measured some considerable performance wins by moving from rayon to a custom async task system.

It's probably very important to note that the blog post talks about I/O and networking, which are areas where you're likely to see major improvements from async. I'm personally pretty skeptical that a purely-cpu bound task like physics will benefit at all from async - as far as I can tell, the whole physics step is a blocking operation, right?

That being said, I'd be glad to be proven wrong.

neachdainn avatar Mar 31 '21 03:03 neachdainn

I think that the performance that would be gained by Rapier when switching to async would be related to replacing Rayon, which uses thread pools for work and therefore could have a performance disadvantage due to thread context switching. Like @devnought mentioned, async brought some great gains in Bevy, which is by no means network or IO heavy ( after the game is done loading assets anyway ).

Still, we really would have to try it to find out I think.

zicklag avatar Mar 31 '21 13:03 zicklag

Still, we really would have to try it to find out I think.

Absolutely! I'm definitely not trying to say this shouldn't be investigated. And I'm not trying to sound too argumentative about this - I'm trying to learn why this might be an improvement, not shoot it down.

I think that the performance that would be gained by Rapier when switching to async would be related to replacing Rayon, which uses thread pools for work and therefore could have a performance disadvantage due to thread context switching.

I just don't see the point in Rapier where .await would be invoked. Without that, won't it still delegate to a thread pool (what Rayon does) or run it serially (which would be a loss in performance)? I've just never seen a case where async has benefited compute-heavy loads and this is the first time I've ever heard someone argue for it.

@devnought mentioned, async brought some great gains in Bevy, which is by no means network or IO heavy ( after the game is done loading assets anyway ).

In the linked post, async is only ever mentioned alongside I/O and network. Do you know if there is someplace I can read about how Bevy is applying async to CPU-based tasks? As far as I can tell Bevy doesn't use async for compute tasks - the benefits it has gained from moving away from Rayon was due to a change in the thread pool, not by using async.

neachdainn avatar Apr 01 '21 00:04 neachdainn

I just don't see the point in Rapier where .await would be invoked...As far as I can tell Bevy doesn't use async for compute tasks - the benefits it has gained from moving away from Rayon was due to a change in the thread pool, not by using async.

That's a good point. I haven't done a ton of investigation myself into it, but I think you might be right. That would explain it in Bevy's case, so maybe we just use Bevy's thread pool for Rapier then. ;)

You seem to be in the right line of thought I think.

zicklag avatar Apr 01 '21 00:04 zicklag

To be clear, I do see that the task pool uses async but I'm interpreting that as an implementation detail of the thread pool, rather than making the tasks themselves async (if the distinction makes sense).

That would explain it in Bevy's case, so maybe we just use Bevy's thread pool for Rapier then.

Agreed. That's probably worth looking into before trying to make all of Rapier async just to see. It does make me want to do a general comparison between the two thread pool implementations - if Bevy's is so much better than Rayon's, what's stopping Rayon from using it?

Hopefully I'll find time to investigate.

neachdainn avatar Apr 01 '21 00:04 neachdainn

Hey @neachdainn just found another project that might be worth looking into: https://github.com/BVE-Reborn/switchyard.

It's an async executor actually designed for optimizing comput task.

zicklag avatar Apr 08 '21 18:04 zicklag

Closing this issue as not planned. During the past few years I have gained much more experience with async and am convinced it has little to no benefit for compute-only tasks. In my experience Rayon’s parallelism tends to outperform the existing async executors for compute. In addition async introduces a non-negligible amount of code complexity and compilation time.

sebcrozet avatar Mar 23 '24 09:03 sebcrozet