if src.len() < 64 { returnsuper::avx2::adler32_avx2(adler, src);
}
let dot2v = DOT2V;
let zero = _mm512_setzero_si512(); letmut vs1; letmut vs2;
while src.len() >= 64 {
vs1 = _mm512_zextsi128_si512(_mm_cvtsi32_si128(adler0 as i32));
vs2 = _mm512_zextsi128_si512(_mm_cvtsi32_si128(adler1 as i32)); letmut k: usize = Ord::min(src.len(), NMAX as usize);
k -= k % 64; letmut vs1_0 = vs1; letmut vs3 = _mm512_setzero_si512(); /* We might get a tad bit more ILP here if we sum to a second register in the loop */ letmut vs2_1 = _mm512_setzero_si512(); letmut vbuf0; letmut vbuf1;
/* Manually unrolled this loop by 2 for an decent amount of ILP */ while k >= 128 { /* vs1=adler+sum(c[i]) vs2=sum2+64vs1+sum((64-i+1)c[i])
*/
vbuf0 = _mm512_loadu_si512(src.as_ptr().cast::<__m512i>());
vbuf1 = _mm512_loadu_si512(src.as_ptr().cast::<__m512i>().add(1));
src = &src[128..];
k -= 128;
letmut vs1_sad = _mm512_sad_epu8(vbuf0, zero);
vs1 = _mm512_add_epi32(vs1, vs1_sad);
vs3 = _mm512_add_epi32(vs3, vs1_0); /* multiply-add, resulting in 16 ints. Fuse with sum stage from prior versions, as we now have the dp
* instructions to eliminate them */
vs2 = _mm512_dpbusd_epi32(vs2, vbuf0, dot2v);
const INPUT: [u8; 128] = { letmut array = [0; 128]; letmut i = 0; while i < array.len() {
array[i] = i as u8;
i += 1;
}
array
};
#[test] fn start_alignment() { // SIMD algorithm is sensitive to alignment; for i in0..16 { for start in [crate::ADLER32_INITIAL_VALUE as u32, 42] { let avx512 = unsafe { adler32_avx512(start, &INPUT[i..]) }; let rust = crate::adler32::generic::adler32_rust(start, &INPUT[i..]);
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.