Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unity JobSystem schedule pattern #7773

Closed
iamabigartist opened this issue Feb 21, 2023 · 4 comments
Closed

Unity JobSystem schedule pattern #7773

iamabigartist opened this issue Feb 21, 2023 · 4 comments
Labels
A-ECS Entities, components, systems, and events A-Tasks Tools for parallel and async work C-Feature A new feature, making something new possible

Comments

@iamabigartist
Copy link

What problem does this solve or what need does it fill?

Sometimes I don't really need the ECS framework but only need the schedule, for example:

  1. Plan all the tasks in a heavy-computation framework such as voxel generation for one generation requirement and run it, the framework generation process should be seen as a whole single system.
  2. Push tasks and generate the tasks dependency graph dynamically in one planning system and run the graph, once per frame. It's for situations like complex damage and effect dealing between characters.

What solution would you like?

Let the user have the ability to fully determine the behavior of the scheduling tool.

Example:

fn task1()...

fn plan1_system(mut commands: Commands){
    commands.spawn(MyTask::new(task1));
    ...
}
fn schedule_system(tasks: Query<&MyTask>,mut scheduler: Scheduler) {
    for task in tasks{scheduler(task,task.dependency); }
    scheduler.complete();//The system completes when the graph completes.
} 
fn main(){
    App::new().add_system(...)
    ...
    .add_system(
        schedule_system
     .after(Label::BeforeExecution))
     .before(Label::AfterExecution)
    )
    .add_system(...)
    ...
}

What alternative(s) have you considered?

#4090 I find the method run_schedule in this issue useful but the current World struct doesn't have it in bevy 0.9.1.
#7707 use commands to add one-shot systems but it seems only to support sequential execution.

@iamabigartist iamabigartist added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels Feb 21, 2023
@james7132 james7132 added A-ECS Entities, components, systems, and events and removed S-Needs-Triage This issue needs to be labelled labels Feb 21, 2023
@james7132
Copy link
Member

james7132 commented Feb 24, 2023

You can already do this with TaskPool and its newtypes. It doesn't have the same dependency graph that Unity has, but you can do the same with Task<T> and async/await, it even lets you pass a value through. Task<T> is Send/Sync, so you can embed it inside your own components. schedule.complete() can be replaced with futures_lite::block_on on a provided task.

AsyncComputeTaskPool is explicitly made to support long running, potentially multi-frame computations that do not block the system scheduler.

@james7132 james7132 added the A-Tasks Tools for parallel and async work label Feb 24, 2023
@iamabigartist
Copy link
Author

iamabigartist commented Feb 25, 2023

Well, are the codes behind ecs system and task the same, with equal optimizations? Like vectorization and so on.

@james7132
Copy link
Member

Unlike Unity, we use the same compiler for every part of the produced binary. Enabling higher optimization levels and LTO (as does Unity's Burst compiler), will result in them applying universally.

As for the backing implementation for ECS systems and tasks, they're identical. ECS systems are tasks running on the same implementation of task executors underneath it all. The main difference is that we segregate the available threads into segments for use case. These currently include Compute (where ECS systems run), Async Compute (where long running CPU-bound operations should run), and IO (short-lived IO bound tasks). This is to prevent longer blocking tasks, like those in Async Compute, from blocking more latency sensitive operations in IO and Compute.

@james7132
Copy link
Member

Beyond the documentation and use case of tasks, this issue is probably inactionable. We can definitely expose a more unity-like API for tasks, or a third-party crate can definitely do so, but the core functionality necessary here is already in the engine. Closing this out for now. Feel free to repoen if you feel strongly that we should change the tasks API to either match Unity's or is insufficient for fulfilling your use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events A-Tasks Tools for parallel and async work C-Feature A new feature, making something new possible
Projects
None yet
Development

No branches or pull requests

2 participants