Vectorize BMP string#131170
Conversation
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @dotnet/area-system-formats-asn1, @bartonjs, @vcsjones |
There was a problem hiding this comment.
Pull request overview
This PR introduces a vectorized implementation of ASN.1 BMPString (big-endian UCS-2 without surrogates) encode/decode logic in BMPEncoding, aiming to improve throughput on larger inputs while preserving scalar behavior for validation and exact error indexing.
Changes:
- Add
Vector<ushort>-based fast paths for BMPString encode (GetBytes) and decode (GetChars), including big-endian handling and surrogate detection. - Split
BMPEncodingintopartialimplementations fornetvs downlevel builds, keeping max-count logic in the shared file. - Add reader/writer tests covering vector boundary lengths, bounds safety (
BoundedMemory), and surrogate detection index correctness.
Show a summary per file
| File | Description |
|---|---|
| src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnCharacterStringEncodings.net.cs | Adds vectorized BMPEncoding encode/decode with endian swap + surrogate scanning. |
| src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnCharacterStringEncodings.downlevel.cs | Restores scalar BMPEncoding implementation for downlevel targets. |
| src/libraries/System.Formats.Asn1/src/System/Formats/Asn1/AsnCharacterStringEncodings.cs | Makes BMPEncoding partial and retains max byte/char count logic. |
| src/libraries/System.Formats.Asn1/tests/Writer/WriteBMPString.cs | Adds vector-boundary + surrogate-index writer regression tests and bounds checks. |
| src/libraries/System.Formats.Asn1/tests/Reader/ReadBMPString.cs | Adds vector-boundary + surrogate-index reader regression tests and bounds checks. |
Copilot's findings
- Files reviewed: 5/5 changed files
- Comments generated: 1
|
@vcsjones not sure if it matters, but currently for loop shapes that load more than one element (either SIMD or BinaryOperations.*) it's more jit friendly to use code like while (span.Length >= <const>)
{
var vec = Vector.Create(span); // or any other operation that loads from/saves to span slice.
span = span.Slice(const);
}the ones you used will lead to redundant checks (hopefully will be optimized in .NET 12.0). Regardless, thanks for using safe code for that 🙂 |
Hm yeah that gave a nice 20~25% performance bump. |
As a follow up to #131109, this introduces vectorization for the
BMPEncoding.BMPEncoding is big-endian UCS-2 encoding. It is a subset of UTF-16-BE, with the exception that it is truly fixed width and only supports plane 0 without the surrogate pairs.
Performance is largely improved across the board. Small inputs, like country codes, regress ~0.5ns simply because the method body itself has slightly more register pressure. Other inputs like common names, etc. see notable performance improvements.
This also incorporates some feedback about making the SIMD more JIT-friendly into the existing IA5 and VisibleString encoding.
Performance Benchmarks
Source: https://gist.github.com/vcsjones/4b91a33bcae337333cb26d46fd087bf9