-
Notifications
You must be signed in to change notification settings - Fork 5k
Force RyuJIT to optimize the code even if heuristics says it is too big. #6210
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
Comments
How big is "too big"? What exactly is big about the method (code, number of variables)? Give some practical examples. Even non JIT compilers sometimes tone down optimizations for large functions otherwise the compilation time would be prohibitively slow in some cases. |
Forgot to add the code. I am at the phone right now, but look at the LZ4_compress_generic code from the link at issue of the dead code elimination you just responded. |
The following defines control when the JIT decides to stop optimizing and drop to MIN_OPTS mode:
#define DEFAULT_MIN_OPTS_CODE_SIZE 60000 The CodeSize value is total IL bytes and INSTR_COUNT is the total number of IL instructions These values are quite large and are typically only ever reached by some kind of machien generated code. Additionally if you can use crossgen to precompile your code and we do not drop to MIN_OPTS for such cases. |
Looking at the source code for LZ4_compress_generic code it seems unlikely that you would hit any of these limits with that code. the actual code can be found at: https://github.com/Corvalius/ravendb/blob/lz4-131/src/Sparrow/Compression/LZ4.cs |
@briansull then there is something else preventing even aggressive inlining. I will probably have to dig further to understand the reason. I will keep you posted of anything I can gather. If you can point me into any doc that explain how to dump the jit states would be great. |
You can set COMPlus_JitDump to the method name, and then search the dump output for "OPTIONS: opts.MinOpts() ==". It will tell you what it set it to, and there should be some indication just above it as to why. |
Also, there are a number of reasons why methods with AggressiveInlining might not get inlined. If you can drop a checked clrjit.dll into your dotnet install, you can set COMPlus_JitPrintInlinedMethods to get a log of inlining decisions with failure reasons (this is less voluminous than a full jit dump). |
Oh, yes - thanks @AndyAyersMS - I forgot to mention that you need a checked (or debug) jit to get the dump. |
I'm not terribly crazy about removing all the limits. However, I am guessing that you might be running into this in a method that has lots of checks against generic parameter types. IMO, that should be a well-supported practice for generic programming, and it would be nice not to penalize such code (at least in the struct case, which as @mikedn pointed out is the one that has optimization potential in the current generics implementation). To that end, another option (that has occurred to me, though I confess I haven't gotten any farther than thinking about it) would be for the JIT to attempt to identify such patterns BEFORE applying the heuristics for minopts or inlining - I just don't know how costly such a heuristic might be that early in the JIT (i.e. when we're just looking at bytecode). |
For example |
Actually adding the |
Yep, there's a jit limitation about inlining conditional throws in methods that return values. Not sure how hard this limitation would be to remove. For now you can work around it by removing the throw, calling a helper method to do the throw, or returning the result via an out param and changing the method return type to void. Calling a helper is probably the way to go. |
I encountered "No inlining for THROW within a non-void conditional" once. |
Confirming the throw and class are preventing optimization here. At least in this case the problem isnt the heuristic, though I believe that if the limits exist, we should be able to have the ability to disable them. |
@redknightlois if this is still relevant let us know. The inlining block you hit was removed in dotnet/coreclr#8038. |
Haven't hit this for a long time. This issue is indeed obsolete by now. |
From what I am seeing, when methods are too big the JIT optimization method will not happen (no inlining, no dead code removal, no dead code optimization).
There are cases where we dont care how much time it will take to optimize it (it will save the cost of optimizing billion times over the lifetime of the method). There should be a way to signal the JIT that heuristic should not apply (if it exist I will be thrilled to know how to do that).
The idea would be following the pattern of
[MethodImpl(MethodImplOptions.AggressiveInlining)]
and[MethodImpl(MethodImplOptions.NoOptimization)]
to have another flag called[MethodImpl(MethodImplOptions.ForceOptimization)]
that would disable the method size heuristic.@CarolEidt I would code the support myself if that is what is required to see this happen ASAP.
The text was updated successfully, but these errors were encountered: