You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Optimize System.Buffers for arm64 using cross-platform intrinsics #35033
This item tracks the conversion of the System.Buffers class to use arm64 intrinsics.
System.Buffers.Text.Base64.DecodeFromUtf8()
System.Buffers.Text.Base64.EncodeToUtf8()
Update for .NET 7
Now that we have cross-platform intrinsics APIs (#49397), these optimizations should be completed using those APIs instead of adding ARM64-specific intrinsics code paths. The effort could optionally include first measuring performance of these methods with the ARM64-specific intrinsics in place, and then measuring the performance of these methods with the cross-platform intrinsics.
Example use of the new cross-platform intrinsics: #63722
@tannergooding@john-h-k The shift intrinsics went in with #36830. There have been many improvements to System.Runtime.Intrinsics optimization in #33496. Is this work now unblocked?
With a recent HEAD, took the ss2 C# code and (mostly) updated it to use Vector128.
On Arm64, most things generated into neon code ... but for Vector128.Shuffle() it generated to a function call:
This code was made by taking Ssse3Decode(), replacing Sse2 with Vector128, then fixing up the function calls. Quite possible there's an obvious mistake on my end.
These all require sequential registers - which AIUI is quite a big task to implement.
Can we still do the routine without them?
The tbl4q instructions can be broken down to 4 tbx instructions + some extra indexing.
the LD4 and ST3 could be replaced by multiple LD and ST instructions. But would then require manual interleaving. I think that can be done using zip/unzp.
Or, it's possible may be able to remove the interleaving requirement from the algorithm.
These changes would make the function non-optimal, but it should still be faster than the sequential version.
@a74nh - Just FYI, we have hardware intrinsics APIs exposed under System.Runtime.Intrinsics.Arm.AdvSimd namespace, in case we can use some of them to optimize and until we add the missing APIs.
Activity
john-h-k commentedon Apr 23, 2020
I can give this a shot
john-h-k commentedon Apr 24, 2020
These ARM64 intrinsics are missing to make the code "worthwhile":
Tracked by #32512:Done!Tracked by #33398:
Tracked by #1277:Done!These helper methods could be accelerated to help it and are tracked in #33496:
These intrinsics could be introduced to maximise perf:
john-h-k commentedon Apr 24, 2020
john-h-k@adeea36
Draft commit, most that can be done until necessary intrinsics are added
tannergooding commentedon Apr 24, 2020
Thanks @john-h-k, as per our conversation on Discord, I'll ping you once the necessary intrinsics are added so you can make further progress.
BruceForstall commentedon Jun 3, 2020
@tannergooding @john-h-k The shift intrinsics went in with #36830. There have been many improvements to System.Runtime.Intrinsics optimization in #33496. Is this work now unblocked?
tannergooding commentedon Jun 3, 2020
Yes, this should be unblocked now.
BruceForstall commentedon Jun 11, 2020
@john-h-k Are you planning to try and finish this for .NET 5, now that it's unblocked?
tannergooding commentedon Jun 11, 2020
If not, we'll have 3-4 people free to help tackle the remaining issues from #33308 on Monday.
CC. @jeffhandley
john-h-k commentedon Jun 11, 2020
Yes, I should be. I just need to benchmark the 2 possible impls I've got locally, either on my old Pi2b or I can get a friend to do it on newer device
31 remaining items
a74nh commentedon May 20, 2022
We are looking at this....
With a recent HEAD, took the ss2 C# code and (mostly) updated it to use Vector128.
On Arm64, most things generated into neon code ... but for Vector128.Shuffle() it generated to a function call:
Annotated IR dump of part of the function:
a74nh commentedon May 20, 2022
The above dump was using
public static Vector128 Shuffle(Vector128 vector, Vector128 indices)
tannergooding commentedon May 20, 2022
Can you share the managed code that was being used here, preferably including the
Shufflecall and how its arguments are being passed in?a74nh commentedon May 20, 2022
This code was made by taking Ssse3Decode(), replacing Sse2 with Vector128, then fixing up the function calls. Quite possible there's an obvious mistake on my end.
a74nh commentedon May 23, 2022
Although - Lack of an Arm64 version of shuffle isn't surprising given there is not obvious match to the instruction
a74nh commentedon May 23, 2022
From the top of Base64Decoder.cs:
// AVX2 version based on https://github.com/aklomp/base64/tree/e516d769a2a432c08404f1981e73b431566057be/lib/arch/avx2
// SSSE3 version based on https://github.com/aklomp/base64/tree/e516d769a2a432c08404f1981e73b431566057be/lib/arch/ssse3
Plan is to base the Arm64 version on the Neon version from the same repo:
https://github.com/aklomp/base64/blob/e516d769a2a432c08404f1981e73b431566057be/lib/arch/neon64/dec_loop.c
Due to this being based on table looks instead of shuffles, there is likely to be no sharing between the X86 and Arm64 version.
kunalspathak commentedon May 23, 2022
And that should be fine.
a74nh commentedon May 24, 2022
In order to reuse the aklomp algorithm, there are still missing API functions:
These all require sequential registers - which AIUI is quite a big task to implement.
Can we still do the routine without them?
kunalspathak commentedon May 24, 2022
@a74nh - Just FYI, we have hardware intrinsics APIs exposed under
System.Runtime.Intrinsics.Arm.AdvSimdnamespace, in case we can use some of them to optimize and until we add the missing APIs.https://source.dot.net/#System.Private.CoreLib/AdvSimd.PlatformNotSupported.cs,f54d7472d19d4e2b
EgorBo commentedon May 24, 2022
can the byte-versions be used instead here?
AdvSimd.VectorTableLookupandAdvSimd.Arm64.VectorTableLookupI see the x64 code uses byte indices
a74nh commentedon May 25, 2022
Those are the single register version - which we can use but we'll need to use 4 of them. So, doable but not optimal.
a74nh commentedon Jun 7, 2022
An implementation of DecodeFromUtf8 without using LD4/ST3/TBX4 is here: #70336
Currently getting 3x slowdown using it. If can't make it faster, then probably best waiting for LD4/ST3/TBX4
kunalspathak commentedon Jun 20, 2022
Closed by #70654