Skip to content

ici/crc: add x86 SSE4.2 + PCLMULQDQ hardware acceleration for BPv7/CFDP CRCs - #112

Open
zebastian wants to merge 1 commit into
nasa-jpl:integrationfrom
zebastian:sse-optimized-crc
Open

ici/crc: add x86 SSE4.2 + PCLMULQDQ hardware acceleration for BPv7/CFDP CRCs#112
zebastian wants to merge 1 commit into
nasa-jpl:integrationfrom
zebastian:sse-optimized-crc

Conversation

@zebastian

Copy link
Copy Markdown
Contributor

Accelerate the two CRC polynomials on the ION data path with x86 intrinsics, selected at run time so a single binary still runs on CPUs that lack the instructions:

  • CRC-32C (poly 0x1EDC6F41): use the SSE4.2 crc32 instruction, which computes exactly this reflected polynomial. Wired into both ion_CRC32_1EDC6F41_C and ion_CRC32_1EDC6F41_C_slice (BPv7 block CRCs, CFDP checksums). ~2.2x over the slice-by-16 table.

  • CRC-16/X-25 (poly 0x1021): no dedicated instruction exists, so fold 16-byte blocks with PCLMULQDQ carry-less multiply and reduce the result with the byte-wise table. Fold constants reflect(x^143 mod P) and reflect(x^79 mod P). ~2.6x over the slice-by-8 table.

Detection is via __builtin_cpu_supports(); each accelerated routine carries a per-function target attribute so the rest of the object stays at the baseline ISA (no -msse4.2/-mpclmul build flags, no SIGILL on older CPUs). Output is bitwise-identical to the existing table routines, verified exhaustively across all offsets, lengths, and accumulation boundaries. Guarded to x86/x86_64 GCC/Clang; other polynomials and platforms fall through to the table paths unchanged.

CRC16 PCLMULQDQ: 9.20 GB/s vs 3.51 GB/s slice-by-8 table (~2.6×)
CRC32 SSE4.2: 10.87 GB/s vs. 4.86 GB/s for the existing slice-by-16 table (~2.2×)

…DP CRCs

Accelerate the two CRC polynomials on the ION data path with x86
intrinsics, selected at run time so a single binary still runs on CPUs
that lack the instructions:

- CRC-32C (poly 0x1EDC6F41): use the SSE4.2 crc32 instruction, which
computes exactly this reflected polynomial.  Wired into both
ion_CRC32_1EDC6F41_C and ion_CRC32_1EDC6F41_C_slice (BPv7 block CRCs,
CFDP checksums).  ~2.2x over the slice-by-16 table.

- CRC-16/X-25 (poly 0x1021): no dedicated instruction exists, so fold
16-byte blocks with PCLMULQDQ carry-less multiply and reduce the
result with the byte-wise table.  Fold constants reflect(x^143 mod P)
and reflect(x^79 mod P).  ~2.6x over the slice-by-8 table.

Detection is via __builtin_cpu_supports(); each accelerated routine
carries a per-function target attribute so the rest of the object stays
at the baseline ISA (no -msse4.2/-mpclmul build flags, no SIGILL on
older CPUs).  Output is bitwise-identical to the existing table
routines, verified exhaustively across all offsets, lengths, and
accumulation boundaries.  Guarded to x86/x86_64 GCC/Clang; other
polynomials and platforms fall through to the table paths unchanged.
@zebastian
zebastian requested a review from iondev33 as a code owner July 2, 2026 06:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant