AVX2 Mark Firsts implementation
This commit is contained in:
parent
2fafe11d7c
commit
9c7c6aabc5
@ -213,6 +213,8 @@ static NOINLINE void memset64(u64* p, u64 v, usz l) { for (usz i=0; i<l; i++) p[
|
|||||||
/*AUXEXTEND*/val -= dif; memset32(val, 0, dif); , \
|
/*AUXEXTEND*/val -= dif; memset32(val, 0, dif); , \
|
||||||
/*AUXMOVE*/u32 v = val[j]; val[j] = 0; val[k] = v;)
|
/*AUXMOVE*/u32 v = val[j]; val[j] = 0; val[k] = v;)
|
||||||
|
|
||||||
|
extern void (*const avx2_mark_firsts_u8)(void*,uint64_t,void*,void*);
|
||||||
|
|
||||||
B memberOf_c1(B t, B x) {
|
B memberOf_c1(B t, B x) {
|
||||||
if (isAtm(x) || RNK(x)==0) thrM("∊: Argument cannot have rank 0");
|
if (isAtm(x) || RNK(x)==0) thrM("∊: Argument cannot have rank 0");
|
||||||
u64 n = *SH(x);
|
u64 n = *SH(x);
|
||||||
@ -251,7 +253,17 @@ B memberOf_c1(B t, B x) {
|
|||||||
for (usz i=0; i<n; i++) { u##T j=xp[i]; rp[i]=tab[j]; tab[j]=0; } \
|
for (usz i=0; i<n; i++) { u##T j=xp[i]; rp[i]=tab[j]; tab[j]=0; } \
|
||||||
decG(x); TFREE(tab); \
|
decG(x); TFREE(tab); \
|
||||||
return taga(cpyBitArr(r))
|
return taga(cpyBitArr(r))
|
||||||
if (lw==3) { if (n<8) { BRUTE(8); } else { LOOKUP(8); } }
|
if (lw==3) { if (n<8) { BRUTE(8); } else {
|
||||||
|
#if SINGELI_AVX2
|
||||||
|
TALLOC(u8, tab, 256);
|
||||||
|
u64* rp; B r = m_bitarrv(&rp, n);
|
||||||
|
avx2_mark_firsts_u8(xv, n, rp, tab);
|
||||||
|
TFREE(tab);
|
||||||
|
return r;
|
||||||
|
#else
|
||||||
|
LOOKUP(8);
|
||||||
|
#endif
|
||||||
|
} }
|
||||||
if (lw==4) { if (n<8) { BRUTE(16); } else { LOOKUP(16); } }
|
if (lw==4) { if (n<8) { BRUTE(16); } else { LOOKUP(16); } }
|
||||||
#undef LOOKUP
|
#undef LOOKUP
|
||||||
#define HASHTAB(T, W, RAD, STOP, THRESH) T* xp = (T*)xv; SELFHASHTAB( \
|
#define HASHTAB(T, W, RAD, STOP, THRESH) T* xp = (T*)xv; SELFHASHTAB( \
|
||||||
|
|||||||
@ -161,5 +161,53 @@ fn avx2_member_u8(w0:*void, nw:u64, x0:*void, nx:u64, r0:*void, tab:*void) : voi
|
|||||||
@for (x in *VI~~x0, r in *u32~~r0 over cdiv{nx,32}) r = bitsel{x}
|
@for (x in *VI~~x0, r in *u32~~r0 over cdiv{nx,32}) r = bitsel{x}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn avx2_mark_firsts_u8(x0:*void, n:u64, r0:*void, tab:*void) : void = {
|
||||||
|
vtab:= *VI~~tab
|
||||||
|
init:= VI**(-1)
|
||||||
|
@unroll (vtab over 8) vtab = init
|
||||||
|
|
||||||
|
u:u8 = 0 # Sum of table, either 0 or 256
|
||||||
|
btab:= *i8~~tab
|
||||||
|
def settab{x} = {
|
||||||
|
v:= load{btab, x}
|
||||||
|
u-= u8~~v # u tracks the total of btab
|
||||||
|
store{btab, x, 0}
|
||||||
|
v
|
||||||
|
}
|
||||||
|
|
||||||
|
# Do first 64 values with a scalar loop
|
||||||
|
x:= *u8~~x0
|
||||||
|
i:u64 = 64; if (n<=64) i=n
|
||||||
|
rw:u64 = 0
|
||||||
|
@for (x over j to i) rw|= u64~~cast_i{i64,settab{x}} & ((u64~~1)<<j)
|
||||||
|
store{*u64~~r0, 0, rw}
|
||||||
|
|
||||||
|
def {bitsel, reload_tab} = bittab_selector{readbytes{*VI~~tab}}
|
||||||
|
xv:= *VI~~x0; r:= *u32~~r0
|
||||||
|
while (i < n) {
|
||||||
|
i0:= i; iw:= i/32
|
||||||
|
m:= bitsel{load{xv, iw}} # Mask of possibly-new values
|
||||||
|
i+= 32
|
||||||
|
if (i > n) m&= (~u32~~0)>>((-n)%32)
|
||||||
|
if (m == 0) { # No new values
|
||||||
|
store{r, iw, m}
|
||||||
|
} else { # Add values to the table and filter m
|
||||||
|
rv:= m
|
||||||
|
do {
|
||||||
|
new:= settab{load{x, i0 + cast_i{u64,ctz{m}}}}
|
||||||
|
m1:= m-1; m&= m1 # Clear last bit
|
||||||
|
rv&= m1 | u32~~cast_i{i32,new} # Clear if not new
|
||||||
|
} while (m != 0)
|
||||||
|
store{r, iw, rv}
|
||||||
|
if (u == 0) { # All bytes seen
|
||||||
|
@for (r over _ from iw+1 to cdiv{n,32}) r = 0
|
||||||
|
return{}
|
||||||
|
}
|
||||||
|
reload_tab{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export{'avx2_mark_firsts_u8', avx2_mark_firsts_u8}
|
||||||
export{'avx2_member_u8', avx2_member_u8}
|
export{'avx2_member_u8', avx2_member_u8}
|
||||||
} # hasarch{'AVX2'}
|
} # hasarch{'AVX2'}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user