(a: &[u8], b: &[u8])
| 40 | #[cfg(target_arch = "x86_64")] |
| 41 | #[target_feature(enable = "avx512f,avx512vpopcntdq")] |
| 42 | unsafe fn avx512(a: &[u8], b: &[u8]) -> u32 { |
| 43 | use std::arch::x86_64::*; |
| 44 | let mut count = 0u32; |
| 45 | let chunks = a.len() / 64; |
| 46 | let rem = a.len() % 64; |
| 47 | for i in 0..chunks { |
| 48 | let va = _mm512_loadu_si512(a.as_ptr().add(i * 64) as *const __m512i); |
| 49 | let vb = _mm512_loadu_si512(b.as_ptr().add(i * 64) as *const __m512i); |
| 50 | let xored = _mm512_xor_si512(va, vb); |
| 51 | let popcnt = _mm512_popcnt_epi64(xored); |
| 52 | let lo = _mm512_extracti64x4_epi64(popcnt, 0); |
| 53 | let hi = _mm512_extracti64x4_epi64(popcnt, 1); |
| 54 | let sum4 = _mm256_add_epi64(lo, hi); |
| 55 | let sum2 = _mm256_add_epi64(sum4, _mm256_permute4x64_epi64(sum4, 0b0100_1110)); |
| 56 | let sum1 = _mm256_add_epi64(sum2, _mm256_permute4x64_epi64(sum2, 0b0001_0001)); |
| 57 | count += _mm256_extract_epi64(sum1, 0) as u32; |
| 58 | } |
| 59 | let base = chunks * 64; |
| 60 | for i in 0..rem { |
| 61 | count += (a[base + i] ^ b[base + i]).count_ones(); |
| 62 | } |
| 63 | count |
| 64 | } |
| 65 | |
| 66 | #[cfg(target_arch = "x86_64")] |
| 67 | #[target_feature(enable = "avx2")] |
no test coverage detected