Expand description
Specialized checksum code for the x86 CPU architecture, based on the efficient algorithm described in the following whitepaper:
Gopal, V., Ozturk, E., Guilford, J., Wolrich, G., Feghali, W., Dixon, M., & Karakoyunlu, D. (2009). Fast CRC computation for generic polynomials using PCLMULQDQ instruction. Intel. (Mirror link: https://fossies.org/linux/zlib-ng/doc/crc-pclmulqdq.pdf, accessed 2024-05-20)
Throughout the code, this work is referred to as βthe paperβ.
On top of the 128-bit PCLMULQDQ implementation, two wider variants use VPCLMULQDQ to fold
several independent 128-bit streams per instruction: an AVX2 variant over 256-bit YMM
registers (8 streams) and an AVX-512 variant over 512-bit ZMM registers (16 streams). Both
rely on VPCLMULQDQ intrinsics stabilized in Rust 1.89 and are only compiled when the
stable_vpclmulqdq cfg is set by build.rs, leaving the crate MSRV unchanged otherwise. The
best variant supported by the running CPU is chosen at runtime.
Each unsafe fn here is unsafe only because it needs the CPU features in its
#[target_feature] list (PCLMULQDQ for reduce128). None of them has a memory-safety
precondition: every load is bounds-checked.
StructsΒ§
EnumsΒ§
- Kind π
- Which SIMD implementation to use, chosen once at construction from the CPUβs features.
ConstantsΒ§
- K1 π
- K2 π
- K3 π
- K4 π
- K5 π
- K_
1024_ πHIGH - K_
1024_ πLOW - K_
2048_ πHIGH - K_
2048_ πLOW - MIN_
AVX512_ πBYTES - MIN_
FOLD_ πBY_ 4_ BYTES - P_X π
- U_PRIME π
FunctionsΒ§
- calculate π β
- calculate_
avx2 π β - 256-bit
VPCLMULQDQvariant: 8 streams across fourYMMregisters (two lanes each), folding two streams per carry-less multiply. - calculate_
avx512 π β - 512-bit
VPCLMULQDQvariant: 16 streams across fourZMMregisters (four lanes each), folding four streams per carry-less multiply. - get π
- Loads the next 16 bytes of
aas a vector and advancesapast them. - get256 π β
- get512 π β
- partial_
words π - Packs a final partial block of 1..=15 bytes into two zero-padded little-endian words, using overlapping loads. Building it in registers avoids copying through a stack buffer, whose narrow stores the following 16-byte load cannot forward from.
- reduce128 π β
- reduce256 π β
- reduce512 π β
- reduce_
128_ π βto_ crc - Folds any remaining 16-byte chunks into
x, then folds a final partial (< 16byte) block with a byte-shift, reduces from 128 to 32 bits with a Barrett reduction, and returns the CRC. Shared by all of the fold implementations.