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

Inline trivial methods in bevy_hierarchy #11332

Merged

Conversation

nicopap
Copy link
Contributor

@nicopap nicopap commented Jan 13, 2024

Objective

In #11330 I found out that Parent::get didn't get inlined, even with LTO on!

This means that just to access a field, we have an instruction cache invalidation, we will move some registers to the stack, will jump to new instructions, move the field into a register, then do the same dance in the other direction to go back to the call site.

Solution

Mark trivial functions as #[inline].

inline(always) may increase compilation time proportional to how many time the function is called and the size of the function marked with inline. Since we mark as inline functions that consists in a single instruction, the cost is absolutely negligible.

I also took the opportunity to inline other functions. I'm not as confident that marking functions calling other functions as inline works similarly to very simple functions, so I used inline over inline(always), which doesn't have the same downsides as inline(always).

More information on inlining in rust: https://nnethercote.github.io/perf-book/inlining.html

In bevyengine#11330 I found out that `Parent::get` didn't get inlined, **even with
LTO on**! Not sure what's up with that, but marking functions that
consist of a single call as `inline(always)` has no downside.

`inline(always)` may increase compilation time proportional to how
many time the function is called **and the size of the function marked
with `inline`**. Since we mark as `inline` no-ops functions, there is no
cost to it.

I also took the opportunity to `inline` other functions. I'm not as
confident that marking functions calling other functions as `inline`
works similarly to very simple functions, so I used `inline` over
`inline(always)`.
@nicopap nicopap added C-Performance A change motivated by improving speed, memory usage or compile times A-Hierarchy Parent-child entity hierarchies labels Jan 13, 2024
@mockersf mockersf 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 Jan 13, 2024
@mockersf
Copy link
Member

mockersf commented Jan 13, 2024

would be nice to see numbers on this, but I'm not sure we have an benchmark or a stress test that would show it

@alice-i-cecile
Copy link
Member

animated_foxes (which should be reasonably heavy on these ops) shows no direct perf changes on quick inspection. Regardless, this seems sensible.

@alice-i-cecile alice-i-cecile added this pull request to the merge queue Jan 13, 2024
Merged via the queue into bevyengine:main with commit a634075 Jan 13, 2024
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Hierarchy Parent-child entity hierarchies 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.

4 participants