Use a possibly-overlapping word and constant-length loop in k/bool, like ⊣`
This commit is contained in:
parent
302c2f926f
commit
e898a81d68
@ -782,13 +782,27 @@ B slash_c2(B t, B w, B x) {
|
||||
u64* rp; r = m_bitarrv(&rp, s);
|
||||
#if SINGELI_AVX2
|
||||
if (wv <= 256) si_constrep_bool(wv, xp, rp, s);
|
||||
else
|
||||
#elif SINGELI
|
||||
if (wv <= 64) si_constrep_bool(wv, xp, rp, s);
|
||||
else
|
||||
if (wv <= 128) si_constrep_bool(wv, xp, rp, s);
|
||||
#else
|
||||
if (wv <= 64) { BOOL_REP_XOR_SCAN(wv) }
|
||||
#endif
|
||||
if (wv <= 256) { BOOL_REP_XOR_SCAN(wv) }
|
||||
else { BOOL_REP_OVER(wv, xlen) }
|
||||
else {
|
||||
// Like BOOL_REP_OVER but predictable
|
||||
u64 ri=0, c=0; usz j=0;
|
||||
usz n=wv/64-1;
|
||||
for (usz i = 0; i < xlen; i++) {
|
||||
u64 v = -(1 & xp[i/64]>>(i%64));
|
||||
u64 r0 = c ^ ((v^c) << (ri%64));
|
||||
c = v;
|
||||
ri += wv; usz e = ri/64;
|
||||
rp[e-1] = v; // This allows the loop to be constant-length
|
||||
rp[j] = r0;
|
||||
for (usz k=0; k<n; k++) rp[j+1+k] = v;
|
||||
j = e;
|
||||
}
|
||||
if (ri%64) rp[j] = c;
|
||||
}
|
||||
goto atmW_maybesh;
|
||||
} else {
|
||||
u8 xk = xl-3;
|
||||
|
||||
@ -321,6 +321,23 @@ fn rep_const_bool{}(wv:usz, x:*u64, r:*u64, rlen:usz) : void = {
|
||||
rep_const_bool{}(wf, x, t, tlen)
|
||||
rep_const_bool{}(wq, t, r, rlen)
|
||||
}
|
||||
} else if (not hasarch{'AVX2'} and wv >= 64) {
|
||||
# Identical to the non-Singeli case for large wv
|
||||
# but we assume n==0 and drop the loop
|
||||
assert{wv < 128}
|
||||
i:usz = 0
|
||||
ri:usz = 0; j:usz = 0 # Bit index in r; ri/64
|
||||
c:u64 = 0
|
||||
while (j < nw-1) { # e<=j+2 below, so e-1<nw
|
||||
v := -(1 & load{x, i/64}>>(i%64)); ++i
|
||||
r0:= c ^ ((v^c) << (ri%64))
|
||||
c = v
|
||||
ri+= wv; e:= ri/64
|
||||
store{r, e-1, c}
|
||||
store{r, j, r0}
|
||||
j = e
|
||||
}
|
||||
if (ri%64 != 0) store{r, j, c}
|
||||
} else {
|
||||
rep_const_bool_odd{wv, x, r, nw}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user