Vector binary search for 16-bit Member-of in addition to 32 (8 is too slow)

This commit is contained in:
Marshall Lochbaum 2023-11-06 09:37:58 -05:00
parent 11245d385e
commit d154ece51a
2 changed files with 22 additions and 20 deletions

View File

@ -47,7 +47,7 @@ RangeFn getRange_fns[el_f64+1];
GETRANGE(f64, if (!q_fi64(c)) return 0)
#endif
#if SINGELI_AVX2
extern void (*const avx2_member_sort_i32)(uint64_t*,int32_t*,uint64_t,int32_t*,uint64_t);
extern void (**const avx2_member_sort)(uint64_t*,void*,uint64_t,void*,uint64_t);
#endif
@ -338,20 +338,19 @@ B memberOf_c2(B t, B w, B x) {
decG(w); goto dec_x;
}
u8 me = we>xe?we:xe;
if (xia<=(me==el_i8?1:me==el_i16?4:15) && wia>16) {
#if SINGELI_AVX2
if (we==xe && we==el_i32 && xia>1) {
x = C1(and, x); // sort
u64* rp; r = m_bitarrc(&rp, w);
avx2_member_sort_i32(rp, tyany_ptr(x), xia, tyany_ptr(w), wia);
} else
#endif
{
SGetU(x);
r = WEQ(GetU(x,0));
for (usz i=1; i<xia; i++) r = C2(or, r, WEQ(GetU(x,i)));
}
#if SINGELI_AVX2
if (wia>=32>>(we-el_i8) && xia>1 && ((we==el_i16 && xia<32) || (we==el_i32 && xia<16)) && xe<=we && !elChr(TI(x,elType))) {
x = C1(and, x); // sort
if (xe<we) switch (we) { default:UD; case el_i16:x=toI16Any(x);break; case el_i32:x=toI32Any(x);break; }
u64* rp; r = m_bitarrc(&rp, w);
avx2_member_sort[we-el_i16](rp, tyany_ptr(x), xia, tyany_ptr(w), wia);
decG(w); goto dec_x;
}
#endif
if (xia<=(we==el_i8?1:we==el_i16?4:8) && wia>16) {
SGetU(x);
r = WEQ(GetU(x,0));
for (usz i=1; i<xia; i++) r = C2(or, r, WEQ(GetU(x,i)));
decG(w); goto dec_x;
}
#undef WEQ

View File

@ -286,18 +286,21 @@ def bin_search_vec{prim, T, w:*T, wn, x:*T, xn, rp, maxwn & hasarch{'AVX2'}} = {
if (isvec{type{rn}}) store{rnp, 0, rn}
else storeu{rnp, rn}
} else {
out := homMask{b}; def B = type{out}; def wb = width{B}
store{*B~~rp, cdiv{j,wb}, out>>((-j)%wb)}
def B = ty_u{vl}; out := cast_i{B, homMask{b}}
store{*B~~rp, cdiv{j,vl}, out>>((-j)%vl)}
}
}
}
}
if (hasarch{'AVX2'}) {
fn avx2_search_bin{prim, T}(rp:*u64, w:*T, wn:u64, x:*T, xn:u64) : void = {
bin_search_vec{prim, T, w, wn, x, xn, rp, 16}
fn avx2_search_bin{prim, T, maxwn}(rp:*u64, w:*void, wn:u64, x:*void, xn:u64) : void = {
bin_search_vec{prim, T, *T~~w, wn, *T~~x, xn, rp, maxwn}
}
exportT{
'avx2_member_sort',
each{avx2_search_bin{'∊',.,.}, tup{i16,i32}, tup{32,16}}
}
export{'avx2_member_sort_i32', avx2_search_bin{'∊',i32}}
}
def unroll_sizes = tup{4,1}