bevy async compute broke by MSAA in 0.15, 0.16, and 0.17
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## Bevy version
0.14.1 and 0.16.1
## \[Optional\] Relevant system information
8 core processor
## What you did
I copied the unofficial example from here. https://bevy-cheatbook.github.io/fundamentals/async-compute.html
I found that it didnt actually work. I minimized it to the provided file down below and it still didn't work. I then copied the official example and the only thing i had to change to break it was adding a camera
In every scenerio described the main thread hangs itself and the app crashes. I believe this is due to the weird programming going on in the bevy TaskPool or including the main thread in the compute thread pool which allows it no CPU time when I create expensive computations.
## What went wrong
I expect bevy async compute to not block main and not hang the app.
## Additional information
Here is minimal code that breaks the unoffical example
```rs
use bevy::prelude::*;
use bevy::tasks::{AsyncComputeTaskPool, Task, TaskPoolBuilder};
use std::collections::HashMap;
#[derive(Resource, Default)]
struct MyMapGenTasks {
generating_chunks: HashMap>,
}
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.insert_resource(MyMapGenTasks::default())
.add_systems(Startup, setup)
.add_systems(Update, begin_generating_map_chunks)
.run();
}
fn setup(mut commands: Commands) {
commands.spawn(Camera3d::default());
AsyncComputeTaskPool::get_or_init(|| {
TaskPoolBuilder::new()
.num_threads(2)
.stack_size(16 * 1024 * 1024)
.build()
});
}
fn generate_map_chunk() {
let mut sum = 0.0;
for j in 1..u32::MAX {
sum += (j as f32).sin().cos().tan().sqrt() + j as f32 * 0.0001;
}
println!("sum: {}", sum);
}
fn begin_generating_map_chunks(mut my_tasks: ResMut) {
let task_pool: &'static AsyncComputeTaskPool = AsyncComputeTaskPool::get();
for chunk_coord in 0..1000 {
if my_tasks.generating_chunks.contains_key(&chunk_coord) {
continue;
}
let task = task_pool.spawn(async move { generate_map_chunk() });
my_tasks.generating_chunks.insert(chunk_coord, task);
}
}```
And there is code replacement that breaks the official example
```rs
// Pretend this is a time-intensive function. :)
async fn generate_map_chunk() {
let mut sum = 0.0;
for j in 1..u32::MAX {
sum += (j as f32).sin().cos().tan().sqrt() + j as f32 * 0.0001;
}
println!("sum: {}", sum);
}
generate_map_chunk().await;```
(i also tried a non async generate_map_chunk function.
Contributor guide
Research direction
Start with the provided Rust reproduction using AsyncComputeTaskPool, TaskPoolBuilder, and the added Camera3d, then compare it with Bevy's official async compute example and the unofficial Async Compute documentation. Investigate why the intensive task submission causes the main thread to hang across the reported Bevy versions. Done means the reproduction no longer hangs or crashes while the async computation runs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100