Factor (8×k)/bool as bit-replicate, then byte-replicate

This commit is contained in:
Marshall Lochbaum 2024-08-13 20:52:30 -04:00
parent fc1265b3f2
commit bf69705c82
2 changed files with 14 additions and 9 deletions

View File

@ -768,7 +768,7 @@ B slash_c2(B t, B w, B x) {
u64* xp = bitarr_ptr(x);
u64* rp; r = m_bitarrv(&rp, s);
#if SINGELI
if (si_constrep_bool(wv, xp, rp, s)) ; // Handles small wv
if (wv <= 64) si_constrep_bool(wv, xp, rp, s);
else
#endif
if (wv <= 256) { BOOL_REP_XOR_SCAN(wv) }

View File

@ -59,6 +59,9 @@ exportT{'si_replicate_scan', flat_table{rep_by_scan, ind_types, dat_types}}
# Constant replicate
def incl{a,b} = slice{iota{b+1},a}
def basic_rep = incl{2, 7}
if_inline (not (hasarch{'SSSE3'} or hasarch{'AARCH64'})) {
fn rep_const{T}(wv:u64, x:*void, r:*void, n:u64) : void = {
@ -69,14 +72,11 @@ fn rep_const{T}(wv:u64, x:*void, r:*void, n:u64) : void = {
def has_bytesel_128 = not hasarch{'AVX2'}
def incl{a,b} = slice{iota{b+1},a}
# 1+˝∨`⌾⌽0=div|⌜range
def makefact{divisor, range} = {
def t = table{{a,b}=>0==b%a, divisor, range}
fold{+, 1, reverse{scan{|, reverse{t}}}}
}
def basic_rep = incl{2, 7}
def fact_size = 128
def fact_inds = slice{iota{fact_size},8}
def fact_tab = makefact{basic_rep, fact_inds}
@ -289,17 +289,23 @@ exportT{'si_constrep', each{rep_const, dat_types}}
# Constant replicate on boolean
fn rep_const_bool{}(wv:usz, x:*u64, r:*u64, rlen:usz) : u1 = {
if (wv > 64) return{0}
fn rep_const_bool{}(wv:usz, x:*u64, r:*u64, rlen:usz) : void = {
assert{wv >= 2}; assert{wv <= 64}
nw := cdiv{rlen, 64}
if (wv&1 == 0) {
p := ctz{wv | 8} # Power of two for second replicate
wf := wv>>p
if (wf == 1) {
rep_const_bool_div8{wv, x, r, nw}
} else if (hasarch{'SSSE3'} and p == 3 and wv <= 8*select{basic_rep, -1}) {
# (higher wv double-factors, which doesn't work with in-place pointers)
tlen := rlen / wf
t := r + cdiv{rlen, 64} - cdiv{tlen, 64}
rep_const_bool{}(8, x, t, tlen)
rep_const{select{dat_types,0}}(promote{u64,wf}, *void~~t, *void~~r, promote{u64,tlen/8})
} else {
tlen := rlen>>p
wq := usz~~1<<p
tlen := rlen >> p
wq := usz~~1 << p
if (p == 1 and (not hasarch{'SSSE3'} or wv>=24)) {
# Expanding odd second is faster
tlen = rlen / wf
@ -312,7 +318,6 @@ fn rep_const_bool{}(wv:usz, x:*u64, r:*u64, rlen:usz) : u1 = {
} else {
rep_const_bool_odd{wv, x, r, nw}
}
1
}
def rep_const_bool_div8{wv, x, r, nw} = { # wv in 2,4,8