int is_new_avx2()

in src/random/sampling_avx2.c [86:117]


int is_new_avx2(IN const idx_t *wlist, IN const size_t ctr)
{
  bike_static_assert((sizeof(idx_t) == sizeof(uint32_t)), idx_t_is_not_uint32_t);

  REG_T idx_ctr = SET1_I32(wlist[ctr]);

  for(size_t i = 0; i < ctr; i += REG_DWORDS) {
    // Comparisons are done with SIMD instructions with each SIMD register
    // containing REG_DWORDS elements. We compare registers element-wise:
    // idx_ctr = {8 repetitions of wlist[ctr]}, with
    // idx_cur = {8 consecutive elements from wlist}.
    // In the last iteration we consider wlist elements only up to ctr.

    REG_T    idx_cur = LOAD(&wlist[i]);
    REG_T    cmp_res = CMPEQ_I32(idx_ctr, idx_cur);
    uint32_t check   = MOVEMASK(cmp_res);

    // Handle the last iteration by appropriate masking.
    if(ctr < (i + REG_DWORDS)) {
      // MOVEMASK instruction in AVX2 compares corresponding bytes from
      // two given vector registers and produces a 32-bit mask. On the other hand,
      // we compare idx_t elements, not bytes, so we multiply by sizeof(idx_t).
      check &= MASK((ctr - i) * sizeof(idx_t));
    }

    if(check != 0) {
      return 0;
    }
  }

  return 1;
}