-
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
[interp] Intrinsify IndexOfOrLessThan #40705
Conversation
Speeds up json deserialization by 5-10%
Tagging subscribers to this area: @BrzVlad |
@@ -1895,6 +1895,11 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas | |||
!strncmp ("System.Runtime.Intrinsics", klass_name_space, 25) && | |||
!strcmp (tm, "get_IsSupported")) { | |||
*op = MINT_LDC_I4_0; | |||
} else if (!strcmp (m_class_get_image (target_method->klass)->assembly_name, "System.Text.Json") && | |||
!strcmp (klass_name_space, "System.Text.Json") && | |||
!strcmp (klass_name, "JsonReaderHelper")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if this check is rigorous enough
The strategy of intrinsifyng random methods in up-stack libraries can quickly result into unmaintainable codebase. Is it really that important to speed up json parsing by 5-10% with the interpreter? I think we are striking a wrong balance between performance and maintainability here. |
I'd also provide simple for-loops implementations for different "unrolled by hands" things over BCL, e.g. https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs#L98-L186 |
Would it be better to provide the small simpler implementations in C#? We have prior art for this - look for |
Here is my overall opinion on interp/bcl interaction.
This is more of a theoretical perspective. Given that, in practice we might want to have some perf gains faster, I'm fine with some temporary uglier changes here and there. |
Do we have a list of the critical end-to-end wasm scenarios somewhere? How much is this moving the needle on these scenarios? |
Beyond general performance, improving JSON Serialization/Deserialization speed was identified as a key metric for the wasm net5.0 release. Adding @danroth27 more details. |
Yes, for .NET 5 we are focused on optimizing Blazor component rendering, particularly high density UI like you would find in a grid component, and JSON serialization/deserialization. @SteveSandersonMS and @pranavkm can point you to the specific benchmark implementations. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Our benchmarks are located https://github.com/dotnet/aspnetcore/tree/master/src/Components/benchmarkapps/Wasm.Performance and tracked at https://aka.ms/aspnet/benchmarks. |
Do we have goals we are trying to hit with these benchmarks for .NET 5? What is the expected impact of this change on these specific benchmarks? |
also waiting for mono\mono mirror CI results |
@jkotas Yes, the goal for JSON serialization in .NET 5 is to double the performance. We've pretty much hit that goal at this point, but given that when we started this work JSON serialization was over an order of magnitude slower on WebAssembly than on .NET Core, there is still plenty of room for improvement. |
I do have concerns with merging this. This is architecture-wise unsound change. Given that we have hit our performance goals for .NET 5, I think this should be closed. We will get more performance improvements in .NET 6 from AOT that won't require this change and that will deliver orders of magnitude more improvements that this change. |
Even though we've currently hit our perf goals for .NET 5, that doesn't mean that additional perf gains in this area aren't valuable. Could we take this change and the perf gain now for .NET 5, and then file a tracking issue to revert it as part of doing the AoT work in .NET 6? It seems like that would deliver the most value to customers and would address the long-term architecture concern. |
I do not think that this improvement is worth this hack. These hacks tend to live their own life, cause pain, and it is hard to get rid of them. Wasm in .NET 5 is going to be incredibly slow for anything compute intensive. This hack is not going to change what kind of wasm-targeting applications are feasible in .NET 5. |
Note the original PR #39733 added a small bit of C# but in the last commit of that PR it was removed assuming mono intrinsics were less controversial. |
I also added this doc (as a Runtime Discussion) that goes over the serialization performance. |
@jkotas what if these things had similar behavior to cross-gen'ed assemblies that are in the shared framework? I'm not too familiar with the mechanics of how the mono-interpreter-intrinsics work, but it seems like a similar problem and we're OK with the lifecycle/architectural characteristics of crossgen/ngen. |
JIT/crossgen/ngen does not special case random private methods from up-stack assemblies. All methods that are special-cased by the codegen as intrinsics should live in CoreLib. For up-stack assemblies, I am ok with special casing code patterns (ie not special casing private methods with specific names), so that the optimization kicks in for any method that contains specific pattern. A lot of codegen optimizations are like this. Also, System.Text.Json is not the only (json) parser our there. If we were to special case its specific private implementation details by name in codegen or interpreter, it creates unfair playing field for the larger ecosystem. |
Speeds up json deserialization by 5-10%
Following discussion from #39733