/// # Safety /// /// The methods of this struct should only be used on x86_64 systems that support the `pclmulqdq` /// instruction, and SSE2 and SSE4.1 instruction sets. #[derive(Debug, Clone, Copy)] #[cfg(target_arch = "x86_64")] pub(crate) struct Accumulator { pub(super) fold: [__m128i; 4],
}
// zlib-ng uses casts and a floating-point xor instruction here. There is a theory that // this breaks dependency chains on some CPUs and gives better throughput. Other sources // claim that casting between integer and float has a cost and should be avoided. We can't // measure the difference, and choose the shorter code. self.fold[3] = _mm_xor_si128(self.fold[3], xmm_a0)
}
}
// Technically the CRC functions don't even call this for input < 64, but a bare minimum of 31 // bytes of input is needed for the aligning load that occurs. If there's an initial CRC, to // carry it forward through the folded CRC there must be 16 - src % 16 + 16 bytes available, which // by definition can be up to 15 bytes + one full vector load. */ let first = init_crc != CRC32_INITIAL_VALUE;
assert!(src.len() >= 31 || !first);
if COPY {
assert_eq!(dst.len(), src.len(), "dst and src must be the same length")
}
if src.len() < 16 { if src.is_empty() { return;
}
partial_buf.0[..src.len()].copy_from_slice(src);
xmm_crc_part = unsafe { _mm_load_si128(partial_buf.0.as_mut_ptr() as *mut __m128i) }; if COPY {
dst[..src.len()].copy_from_slice(&partial_buf.0[..src.len()]);
}
} else { // SAFETY: [u8; 16] can safely transmute into _m128i. let (before, _, _) = unsafe { src.align_to::<__m128i>() };
#[allow(unused_unsafe)] // because target features 1.1 if !before.is_empty() {
xmm_crc_part = unsafe { _mm_loadu_si128(src.as_ptr() as *const __m128i) }; if COPY { unsafe { _mm_storeu_si128(dst.as_mut_ptr() as *mut __m128i, xmm_crc_part) };
dst = &mut dst[before.len()..];
} else { let is_initial = init_crc == CRC32_INITIAL_VALUE;
while src.len() >= 64 { let n = unsafe { self.progress::<4, COPY>(dst, &mut src, &mut init_crc) };
dst = &mut dst[n..];
}
if src.len() >= 48 { let n = unsafe { self.progress::<3, COPY>(dst, &mut src, &mut init_crc) };
dst = &mut dst[n..];
} elseif src.len() >= 32 { let n = unsafe { self.progress::<2, COPY>(dst, &mut src, &mut init_crc) };
dst = &mut dst[n..];
} elseif src.len() >= 16 { let n = unsafe { self.progress::<1, COPY>(dst, &mut src, &mut init_crc) };
dst = &mut dst[n..];
}
}
if !src.is_empty() {
debug_assert!(src.len() <= 16); unsafe { // SAFETY: src and xmm_crc_part don't overlap. xmm_crc_part is statically // guaranteed to be 16 bytes, and in earlier code we advanced the src slice such // that it's less than 16 bytes.
core::ptr::copy_nonoverlapping(
src.as_ptr(),
&mut xmm_crc_part as *mut _ as *mut u8,
src.len(),
); if COPY {
_mm_storeu_si128(partial_buf.0.as_mut_ptr() as *mut __m128i, xmm_crc_part);
core::ptr::copy_nonoverlapping(
partial_buf.0.as_ptr(),
dst.as_mut_ptr(),
src.len(),
);
} self.partial_fold(xmm_crc_part, src.len());
}
}
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet am 2026-08-27)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.