Vectorize custom polynomial CRC-32 and CRC-64#124832
Conversation
|
Tagging subscribers to this area: @dotnet/area-system-io-hashing, @bartonjs, @vcsjones |
There was a problem hiding this comment.
Pull request overview
This pull request implements vectorized CRC computation for CRC-32 (both forward and reflected variants) and CRC-64 (forward only). The changes refactor the existing vectorization code from the Crc32 and Crc64 classes into the respective ParameterSet classes, enabling vectorization support for custom CRC polynomials.
Changes:
- Introduces abstract base classes (
ForwardCrc32,ReflectedCrc32,ForwardCrc64) that handle vectorization using a partial method pattern - Adds
CrcPolynomialHelperclass with aUInt640struct for computing folding and Barrett constants for arbitrary polynomials - Migrates vectorization logic from
Crc32/Crc64static classes to parameter set implementations
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| CrcPolynomialHelper.cs | New helper class for computing CRC folding/Barrett constants using 640-bit arithmetic |
| Crc32ParameterSet.cs | Adds ReflectedCrc32 and ForwardCrc32 abstract base classes with partial method hooks for vectorization |
| Crc32ParameterSet.Vectorized.cs | Implements vectorized CRC-32 computation for both reflected and forward variants |
| Crc32ParameterSet.WellKnown.cs | Updates IEEE 802.3 and CRC-32C to use new base classes with ARM intrinsics support |
| Crc32ParameterSet.Table.cs | Updates table-based implementations to inherit from new base classes |
| Crc32.cs | Removes partial modifier, delegates to parameter set's Update method |
| Crc32.Vectorized.cs | Deleted - logic moved to ParameterSet |
| Crc32.Table.cs | Deleted - table moved to ParameterSet.WellKnown |
| Crc32.Arm.cs | Deleted - ARM intrinsics moved to ParameterSet.WellKnown |
| Crc64ParameterSet.cs | Adds ForwardCrc64 abstract base class with vectorization support |
| Crc64ParameterSet.Vectorized.cs | Implements vectorized forward CRC-64 computation |
| Crc64ParameterSet.WellKnown.cs | Updates ECMA-182 to use ForwardCrc64 base class |
| Crc64ParameterSet.Table.cs | Updates table-based forward implementation to inherit from ForwardCrc64 |
| Crc64.cs | Removes partial modifier, delegates to parameter set's Update method |
| Crc64.Vectorized.cs | Deleted - logic moved to ParameterSet |
| Crc64.Table.cs | Deleted - table moved to ParameterSet.WellKnown |
| System.IO.Hashing.csproj | Updates file references to reflect deletions and additions |
| Crc32Tests_ParameterSet_Custom.cs | Adds test driver for forward CRC-32 with non-standard polynomial |
|
Perf-wise, it's basically unchanged from the current vectorized implementation for CRC-32/IEEE and CRC-64/ECMA.
|
src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32ParameterSet.Vectorized.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32ParameterSet.Vectorized.cs
Show resolved
Hide resolved
src/libraries/System.IO.Hashing/src/System/IO/Hashing/CrcPolynomialHelper.cs
Show resolved
Hide resolved
src/libraries/System.IO.Hashing/src/System/IO/Hashing/CrcPolynomialHelper.cs
Outdated
Show resolved
Hide resolved
tannergooding
left a comment
There was a problem hiding this comment.
SIMD code LGTM and is mostly just a refactoring of the prior logic.
There's some potential future cleanup, but nothing really relevant to the PR here; mostly future work and reducing unnecessary unsafe usage.
src/libraries/System.IO.Hashing/src/System/IO/Hashing/CrcPolynomialHelper.cs
Show resolved
Hide resolved
src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc64ParameterSet.cs
Show resolved
Hide resolved
src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32ParameterSet.cs
Show resolved
Hide resolved
src/libraries/System.IO.Hashing/src/System/IO/Hashing/Crc32ParameterSet.WellKnown.cs
Outdated
Show resolved
Hide resolved
|
/ba-g The failing tests are #125245, not sure why Build Analysis didn't match it. |
With this change, the CRC-32 and CRC-64 computation flows call UpdateVectorized to process as much data as "can" be done (none on .NET Framework, none on Big Endian systems, and up to the last multiple of 128 bits otherwise), then processes the "remainder" with UpdateScalar. UpdateScalar may be table based (most of the time) or a CPU intrinsic (CRC-32/C on x64 or ARM, CRC-32/IEEE on ARM).
This change also brings in more custom polynomial well-known value tests, to corroborate that the polynomial-attached "constants" are being computed correctly.
Fixes #124576.