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

Add a push_light method and use likely/unlikely intrinsics #134

Closed
wants to merge 1 commit into from

Conversation

Zoxc
Copy link

@Zoxc Zoxc commented Dec 5, 2018

This adds a push_light alternative to push which is optimized for inlining and for vectors which fit inside the fixed size.


This change is Reviewable

}

#[cfg(not(feature = "push_light"))]
fn push_light(&mut self, _: T) {}
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand why this is defined if the feature is missing, and why it does nothing.

Copy link
Author

Choose a reason for hiding this comment

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

It's to ensure things still compile

Copy link
Contributor

Choose a reason for hiding this comment

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

It compiles sure, but it doesn't do the right thing, why should it be a noop if the feature is missing? Sounds like a way to have silent bugs.

Copy link
Author

Choose a reason for hiding this comment

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

It's not meaningful to benchmark a feature if it's disabled

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh ok sorry I didn't notice this was an implementation for benchmarks.


trait Vector<T>: for<'a> From<&'a [T]> + Extend<T> + ExtendFromSlice<T> {
fn new() -> Self;
fn push(&mut self, val: T);
fn push_light(&mut self, val: T);
Copy link
Contributor

Choose a reason for hiding this comment

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

IMO this should either not exist when the feature is not enabled, or delegate to push in the default implementation.

@eira-fransham
Copy link
Contributor

So the speedup when the vector isn't spilled is more than 2x (both with and without inlining, I added benchmarks to test it without the inline(never) wrapper). This is especially true when I test::black_box all the V::new calls to prevent LLVM from being too clever. The question I want to ask about this PR is: why not just make this the default behaviour? The slowdown even on massive arrays is relatively small and it's even faster to use push_light for spilled-but-relatively-small smallvecs (once I add black_box), and since we're never going to be able to be as fast as Vec can be for a spilled array we can assume that the user is always expecting that it's more likely than not that the vector will be on the stack.

@Zoxc
Copy link
Author

Zoxc commented Jan 7, 2019

It probably does make sense to make it the default behavior.

@eira-fransham
Copy link
Contributor

eira-fransham commented Jan 7, 2019

Additionally, I would mark this function #[inline] and not #[inline(always)]. You basically never want #[inline(always)] unless you can produce benchmarks proving that it's slower without it. LLVM's inlining heuristics are really good and you can mess up cold code or people optimising for code size if you use inline(always).

@bors-servo
Copy link
Contributor

☔ The latest upstream changes (presumably #169) made this pull request unmergeable. Please resolve the merge conflicts.

@eira-fransham
Copy link
Contributor

Was this ever made the default behaviour? It seems like an easy win.

@mbrubeck
Copy link
Collaborator

We can't make this the default as written, because even without the likely feature it still depends on the unstable assume intrinsic. If this is still a win without any intrinsics then I'd be happy to replace the current push with push_light (and keep the intrinsics behind an optional feature).

@mbrubeck
Copy link
Collaborator

I pushed a rebased version of this PR plus a commit to make push_light the default, in case anyone wants to experiment with it:

master...mbrubeck:light2

At a glance, it looks like this is still a win for bench_push_small even without the assume or likely/unlikely intrinsics.

@eira-fransham
Copy link
Contributor

You can always have a cfg(feature = nightly)

@mbrubeck
Copy link
Collaborator

mbrubeck commented Oct 30, 2019

Yes, the branch I linked above keeps the unstable intrinsics behind an optional feature.

@mbrubeck mbrubeck deleted the branch servo:master September 20, 2023 17:19
@mbrubeck mbrubeck closed this Sep 20, 2023
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.

5 participants