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

Use atomic crossbeam structure to add interior mutability to common::Errors #255

Merged
merged 1 commit into from Sep 11, 2017

Conversation

torkleyy
Copy link
Member

@torkleyy torkleyy commented Sep 9, 2017

This allows fetching Errors without limiting concurrency.

@torkleyy
Copy link
Member Author

cc @Xaeroxe @omni-viral @ebkalderon This should also improve performance for Amethyst in the future, and is the same strategy we should use for events in case we want to implement them as described in amethyst/amethyst#229

@torkleyy torkleyy requested a review from kvark September 11, 2017 05:55
@zakarumych
Copy link
Member

zakarumych commented Sep 11, 2017

@torkleyy I believe that crossbeam's MsQueue will add more overhead than collecting errors that Systems return. There are two reasons.

  • Dynamic allocations on each push.
  • Lock-free algorithm uses loop with CAS

Of course the fact it is optional is a good thing.
But collecting Result<(), !> from System::run will be noop too.

@torkleyy
Copy link
Member Author

@omni-viral I don't think so, but the bigger problem I have with Systems returning Result is that it is a breaking change that forces all users to change all of their system implementations and that you have to add Ok(()) everywhere, even though most systems don't need results. To improve ergonomics, I planned to add a method Errors::execute:

fn run(..) {
    let x = errors.execute(|| {
        let val = do_something_that_can_fail()?;
        
        val + 5
    });

    ints.insert(entity, x);
} 

Just look at these systems used in an actual game built with Specs: https://github.com/agmcleod/ld39/tree/master/src/systems

None of them needs Results and their (performance-wise and syntactical) overhead.

@torkleyy
Copy link
Member Author

The difference here is also that the crossbeam structure only does something if errors get pushed, but the collecting of Results happens every frame. This means the best-case performance (no error), which is the common one, is better with this solution.

@zakarumych
Copy link
Member

zakarumych commented Sep 11, 2017

This means the best-case performance (no error), which is the common one, is better with this solution.

The good reason I often forget about 😄
I always assume worst case scenario.

@torkleyy
Copy link
Member Author

@omni-viral So can I take this as an approval?

src/common.rs Outdated
}

/// Collect all errors into a `Vec`.
pub fn collect(&mut self) -> Vec<BoxedErr> {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe it is better to return draining iterator instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

Crossbeam doesn't offer that, but I could still implement it in this module.

src/common.rs Outdated
/// Collect all errors into a `Vec`.
pub fn collect(&mut self) -> Vec<BoxedErr> {
let mut errors = Vec::new();
while let Some(e) = self.errors.try_pop() {
Copy link
Member

Choose a reason for hiding this comment

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

Isn't there a method to pop all queue at once?

Copy link
Member Author

Choose a reason for hiding this comment

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

No.

Copy link
Member

Choose a reason for hiding this comment

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

I'll take a look if it may be added 😄

…Errors

Add methods

* collect
* drain
* pop_err
* has_error
@torkleyy
Copy link
Member Author

@omni-viral Done.

@torkleyy
Copy link
Member Author

Merging this now, as this is blocking me atm.

bors r+

bors bot added a commit that referenced this pull request Sep 11, 2017
255: Use atomic crossbeam structure to add interior mutability to common::Errors r=torkleyy a=torkleyy

This allows fetching `Errors` without limiting concurrency.
@bors
Copy link
Contributor

bors bot commented Sep 11, 2017

Build succeeded

@bors bors bot merged commit b4773f1 into amethyst:master Sep 11, 2017
@torkleyy torkleyy deleted the cerr branch September 11, 2017 09:07
@zakarumych
Copy link
Member

Great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants