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

[Merged by Bors] - Converted exclusive systems to parallel systems wherever possible #2774

Closed
wants to merge 3 commits into from

Conversation

SarthakSingh31
Copy link
Contributor

@SarthakSingh31 SarthakSingh31 commented Sep 5, 2021

Closes #2767.

Converted:

  • play_queued_audio_system
  • change_window

@github-actions github-actions bot added the S-Needs-Triage This issue needs to be labelled label Sep 5, 2021
@SarthakSingh31 SarthakSingh31 changed the title Convert exclusive systems to parallel systems wherever possible Converted exclusive systems to parallel systems wherever possible Sep 5, 2021
@NiklasEi NiklasEi added C-Code-Quality A section of code that is hard to understand or change C-Performance A change motivated by improving speed, memory usage or compile times and removed S-Needs-Triage This issue needs to be labelled labels Sep 5, 2021
Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thanks for doing this! Left one nit, but it looks great.

We should verify that we're not introducing one-frame delays with new execution order ambiguities. I'm a bit loathe to ask you to do that in this PR; feel free to investigate if you'd like but if it's beyond you we can do a proper cleanup pass for that in a seperate PR.

crates/bevy_winit/src/lib.rs Outdated Show resolved Hide resolved
@SarthakSingh31
Copy link
Contributor Author

SarthakSingh31 commented Sep 5, 2021

It is probably introducing ambiguity and some one-frame delays. From what I understand by default all the exclusive systems run at the start of the stage and this change makes it run in between. I would assume the same applies to gilrs_event_system.

I don't know how to make these systems run first without making them exclusive again or putting labels everywhere. Idk if putting labels everywhere is an acceptable solution, I don't think it is very maintainable.

For Reference:

  • Ambiguity before this change:
    -- "bevy_winit::change_window" and "bevy_audio::audio_output::play_queued_audio_system<bevy_audio::audio_source::AudioSource>"
    
  • Ambiguity after this change:
    -- "bevy_render::camera::camera::camera_system<bevy_render::camera::projection::OrthographicProjection>" and "bevy_winit::change_window"
    -- "bevy_render::camera::camera::camera_system<bevy_render::camera::projection::PerspectiveProjection>" and "bevy_winit::change_window"
    -- "bevy_ui::widget::text::text_system" and "bevy_winit::change_window"
    -- "bevy_ui::flex::flex_node_system" and "bevy_winit::change_window"
    -- "bevy_winit::change_window" and "bevy_text::text2d::text2d_system"
    

@alice-i-cecile
Copy link
Member

Idk if putting labels everywhere is an acceptable solution, I don't think it is very maintainable.

Yeah; there's a larger conversation ongoing about this: see #2747.

I suspect that the change_window system's ambiguities are going to genuinely cause issues. Can we move this into the stage before?

@SarthakSingh31
Copy link
Contributor Author

Can we move this into the stage before?

I think that will exacerbate the issue of one-frame delays because the majority of commands put into the Window::command_queue will probably come from CoreStage::Update. It might be best to keep it as an exclusive system for now. It is hard to say which is better without more testing.

@SarthakSingh31
Copy link
Contributor Author

SarthakSingh31 commented Sep 6, 2021

@alice-i-cecile I did some testing with timing the duration it takes for changes triggered in scale_factor_override.rs example to show up in the flex_node_system (the only consumer of WindowScaleFactorChanged events).

postupdate parallel: 0.549728 ms - 10.027739 ms
postupdate exlcusive: 0.390465 ms - 0.620356 ms
update parallel: 0.390914 ms - 7.55568875 ms 
update exclusive: 7.643498 ms - 11.235118 ms 

I think the parallel ones change the order they are executed in across executions of the binary. They produce extremely varying results.

@alice-i-cecile
Copy link
Member

because the majority of commands put into the Window::command_queue will probably come from CoreStage::Update

Hmm, I agree. We could make another stage :/ I think the best solution here is probably to add a public label to change_window and then have all the other conflicting systems run before it.

I think the parallel ones change the order they are executed in across executions of the binary. They produce extremely varying results.

Yep, that's standard ambiguous ordering behavior :(

@SarthakSingh31
Copy link
Contributor Author

SarthakSingh31 commented Sep 6, 2021

@alice-i-cecile Added the labels in. Ran a benchmark again and now its around 0.302998 ms - 0.411899 ms pretty reliably. There are no more ambiguities reported related to this pr now.

Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic; looks good to me now! Thanks for tackling this.

@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Sep 7, 2021
@alice-i-cecile
Copy link
Member

@SarthakSingh31 can you rebase this on main? :) I'd like to get this merged but there are now merge conflicts

@SarthakSingh31 SarthakSingh31 force-pushed the min_ex_system branch 4 times, most recently from 7c54787 to 562dc29 Compare March 1, 2022 01:53
@SarthakSingh31
Copy link
Contributor Author

@alice-i-cecile rebased. It looks like gilrs_event_system was converted in a different pr so removed anything related to it from this pr.

@mockersf
Copy link
Member

mockersf commented Mar 1, 2022

The system add_clusters in bevy_pbr is an exclusive system that uses Res<Windows> and that would be executed before the change_window system after this change. Is that an issue? @superdump ?

@alice-i-cecile
Copy link
Member

alice-i-cecile commented Mar 1, 2022

The system add_clusters in bevy_pbr is an exclusive system that uses Res and that would be executed before the change_window system after this change. Is that an issue?

My intution is that this should run after, both to preserve existing behavior and for correctness. @SarthakSingh31 can you make that change? We can revert it if our rendering experts tell us otherwise.

@superdump
Copy link
Contributor

superdump commented Mar 1, 2022

The system add_clusters in bevy_pbr is an exclusive system that uses Res<Windows> and that would be executed before the change_window system after this change. Is that an issue? @superdump ?

Hmm. I think the current setup has add_clusters being run first as an exclusive system to ensure the presence of Clusters components on appropriate views, and then update_clusters is a normal system that overwrites the cluster configuration based on the window size. I think that suggests it only has to be correct when update_clusters is run. To complicate things further, I know that update_clusters is going to move to being called from assign_lights_to_clusters in an upcoming PR.

To be clear, add_clusters needs to be run such that the Clusters components are actually added (ie commands are applied to the world) before any of the subsequent clustered forward rendering PostUpdate systems are run. And I think the window sizes only have to be correct at the point of execution of update_clusters currently but it would have to be tested. If possible just preserve current behaviour.

@superdump
Copy link
Contributor

If add_clusters required windows to be correct and it is an exclusive system, then it would then require that change_windows is either exclusive and run before it, or it is run in an earlier stage, right?

@alice-i-cecile
Copy link
Member

If add_clusters required windows to be correct and it is an exclusive system, then it would then require that change_windows is either exclusive and run before it, or it is run in an earlier stage, right?

Huh, change_window is also an exclusive system. In that case, yes.

However, it looks like change_window also has no reason to be exclusive:

fn change_window(world: &mut World) {
.

@mockersf
Copy link
Member

mockersf commented Mar 1, 2022

yup, this pr is changing change_window from exclusive to non exclusive

it seems add_clusters is set as exclusive only for ordering purpose though

@superdump
Copy link
Contributor

yup, this pr is changing change_window from exclusive to non exclusive

it seems add_clusters is set as exclusive only for ordering purpose though

It isn't only for ordering. It inserts Clusters components on views which don't have them. Subsequent systems in PostUpdate expect Clusters to be present. I suppose if you accepted a 1-frame delay in the Clusters component coming into existence then it would be fine.

That said, I don't think add_clusters was specified to necessarily run after change_windows among the exclusive PostUpdate systems, so it could have run after. And, also as said, I think as long as update_clusters runs after change_windows, it should be fine, but we need to test it.

@SarthakSingh31 SarthakSingh31 force-pushed the min_ex_system branch 2 times, most recently from 662d429 to 4f4b478 Compare March 3, 2022 05:59
@SarthakSingh31
Copy link
Contributor Author

@mockersf fixed the ordering and resolved the new merge conflicts. I feel like update_clusters should be reported as ambiguous before this change but it isn't.

Copy link
Contributor

@superdump superdump left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a couple of comments.

Separately, continuing the add_clusters discussion, I think before this PR, add_clusters would run after change_windows with DefaultsPlugins plugin ordering because winit would be initialised before pbr so the change_windows exclusive system would be registered before the add_clusters exclusive system and so change_windows would also be executed before add_clusters.

With this PR change_windows is being moved to after add_clusters because add_clusters is still exclusive and change_windows is not.

As mentioned, I think the important things from a practical perspective are that add_clusters remains exclusive so that clusters components get added to appropriate views before update_clusters is later executed, and change_windows must run before update_clusters. The labelling of change_windows and the ordering condition that update_clusters be run after change_windows satisfies this.

@@ -80,14 +82,16 @@ impl Plugin for PbrPlugin {
// add as an exclusive system
add_clusters
.exclusive_system()
.label(SimulationLightSystems::AddClusters),
.label(SimulationLightSystems::AddClusters)
.after(ModifiesWindows),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think now that change_windows is not exclusive, this will cause a warning to be logged that this system tried to be scheduled after ModifiesWindows and that system doesn’t exist in the exclusive part of PostUpdate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed it

@@ -73,3 +73,6 @@ impl Plugin for WindowPlugin {
}
}
}

#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemLabel)]
pub struct ModifiesWindows;
Copy link
Contributor

@superdump superdump Mar 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can systems have multiple labels, if not then the approach of tagging a system with things it does doesn’t really hold because a system could modify multiple things as well as the windows.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, multiple levels are permitted.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Then this is not a problem.

@alice-i-cecile
Copy link
Member

@SarthakSingh31 can you rebase this? I'd like to merge this in.

@alice-i-cecile
Copy link
Member

bors r+

bors bot pushed a commit that referenced this pull request Apr 25, 2022
)

Closes #2767.

Converted:
- `play_queued_audio_system`
- `change_window`
@IceSentry
Copy link
Contributor

IceSentry commented Apr 25, 2022

I don't know if it's too late now, but it would be nice if this PR used the actual system as a label instead of a new SystemLabel now that we have this feature.

edit: it's too late now

@bors bors bot changed the title Converted exclusive systems to parallel systems wherever possible [Merged by Bors] - Converted exclusive systems to parallel systems wherever possible Apr 25, 2022
@bors bors bot closed this Apr 25, 2022
@SarthakSingh31 SarthakSingh31 deleted the min_ex_system branch April 25, 2022 15:05
exjam pushed a commit to exjam/bevy that referenced this pull request May 22, 2022
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-Code-Quality A section of code that is hard to understand or change C-Performance A change motivated by improving speed, memory usage or compile times S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Convert exclusive systems in Bevy to ordinary systems wherever possible
7 participants