-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
AggressiveInlining not respected when Method grow too large #41692
Comments
Aggressive inline candidates are assumed to be profitable; they bypass the normal profitability checks. So in particular we won't analyze their IL for patterns that might be optimizable. Can you provide a repro for the issues you're seeing? We are trying to be as aggressive as we can without getting into situations where the jit will create enormous methods or use huge amounts of memory while jitting. |
|
Your repro doesn't have
if you put |
Sorry. Not sure what I thought with that sample. I've just reverted some changes, and it appears what is actually happening (I didn't know this was a thing when I first encountered this issue) is I'm hitting the This is unfortunate, but I'm not too sure if JIT can do much about this (besides raising the limit, but I'm sure there are some reasons for the limit being this low). I'll definitely have to keep this in mind, since I often rely heavily on JIT eliminating branches like this at runtime... Apologies again for the incorrect sample 😅 |
@AndyAyersMS Since you are looking into it, assigning this to you. Please help triage this. |
@HurricanKai thanks for the example. The jit should be able to tell after inlining such a method that it wasn't nearly as big as it seemed; I'm trying to think of how it could figure this out ahead of time, or along the way. Ahead of time seems hard; as @EgorBo says, we don't want to spend a lot of time analyzing large methods; and our analysis isn't all that powerful. But checking along the way seems viable -- I think something like the following can work. When the jit sees an That way if the jit is really just touching a fraction of a huge method during importation then the inline can succeed. The only downside is that the jit may spend a bunch of cycles attempting inlines that later are abandoned, but that shouldn't happen too often, and the use of |
Moving to .NET 6. |
Splitting methods with trial and error until they inline is somewhat annoying, but if I'm accurately picturing what you mean by a "binary tree of sorts" then breaking it up in a linear fashion like so may be easier and less tedious. |
Thank you, that is what I did for the functions were I did this manually, and only have few branches, but in some cases I have 1000+ cases and I believe a binary tree like that will yield less IL, so less binary size. |
@HurricanKai any way I can get a repro for this to test out some jit changes? Is the one up above that is |
I believe the https://github.com/dotnet/runtime/files/5158907/OpenGL.zip is the only one that actually reproduced this. I can look at making a simpler repro, if needed. |
It doesn't need to be simpler. I'm not sure how to turn that into something I can compile. |
… opportunities Look for IL patterns in an inlinee that are indicative of type folding. Also track when an inlinee has calls that are intrinsics. Use this to boost the inlinee profitability estimate. Also, allow an aggressive inline inline candidate method to go over the budget when it contains type folding or intrinsics (and so the method may be simpler than it appears). Remove the old criteria (top-level inline) which was harder to reason about. Closes dotnet#43761. Closes dotnet#41692. Closes dotnet#51587. Closes dotnet#47434.
@EgorBo perhaps you can follow up here? |
Not sure we're going to get to this in 6.0, so moving to future. |
Description
JIT will refuse to inline AggressiveInlining methods when Methods grow too large (IL size / too many branches, I'm unsure which one, but I expect IL size)
If I understand AggressiveInlining correctly, this is not intended.
This happened to me in a method like the below, but I've encountered it before:
This does not inline/constant fold, leading to quite the performance hit since now all those comparisons are actual comparisons.
Splitting this into a binary tree of sorts has led to JIT inlining it, and a good performance increase.
Analysis
I think this can be related to #38106
I don't understand JIT very well, but I think this can have multiple causes.
It might be an idea to look for comparisons with constants that "end" the method and prioritize inlining? Looking at the inlinepolicy, which I think is where this kind of thing is decided, this would be difficult, but possible?
category:cq
theme:inlining
skill-level:intermediate
cost:medium
The text was updated successfully, but these errors were encountered: