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* xp = bitarr_ptr(x);
u64* rp; r = m_bitarrv(&rp, s); u64* rp; r = m_bitarrv(&rp, s);
#if SINGELI #if SINGELI
if (si_constrep_bool(wv, xp, rp, s)) ; // Handles small wv if (wv <= 64) si_constrep_bool(wv, xp, rp, s);
else else
#endif #endif
if (wv <= 256) { BOOL_REP_XOR_SCAN(wv) } 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 # 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'})) { if_inline (not (hasarch{'SSSE3'} or hasarch{'AARCH64'})) {
fn rep_const{T}(wv:u64, x:*void, r:*void, n:u64) : void = { 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 has_bytesel_128 = not hasarch{'AVX2'}
def incl{a,b} = slice{iota{b+1},a}
# 1+˝∨`⌾⌽0=div|⌜range # 1+˝∨`⌾⌽0=div|⌜range
def makefact{divisor, range} = { def makefact{divisor, range} = {
def t = table{{a,b}=>0==b%a, divisor, range} def t = table{{a,b}=>0==b%a, divisor, range}
fold{+, 1, reverse{scan{|, reverse{t}}}} fold{+, 1, reverse{scan{|, reverse{t}}}}
} }
def basic_rep = incl{2, 7}
def fact_size = 128 def fact_size = 128
def fact_inds = slice{iota{fact_size},8} def fact_inds = slice{iota{fact_size},8}
def fact_tab = makefact{basic_rep, fact_inds} def fact_tab = makefact{basic_rep, fact_inds}
@ -289,14 +289,20 @@ exportT{'si_constrep', each{rep_const, dat_types}}
# Constant replicate on boolean # Constant replicate on boolean
fn rep_const_bool{}(wv:usz, x:*u64, r:*u64, rlen:usz) : u1 = { fn rep_const_bool{}(wv:usz, x:*u64, r:*u64, rlen:usz) : void = {
if (wv > 64) return{0} assert{wv >= 2}; assert{wv <= 64}
nw := cdiv{rlen, 64} nw := cdiv{rlen, 64}
if (wv&1 == 0) { if (wv&1 == 0) {
p := ctz{wv | 8} # Power of two for second replicate p := ctz{wv | 8} # Power of two for second replicate
wf := wv>>p wf := wv>>p
if (wf == 1) { if (wf == 1) {
rep_const_bool_div8{wv, x, r, nw} 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 { } else {
tlen := rlen >> p tlen := rlen >> p
wq := usz~~1 << p wq := usz~~1 << p
@ -312,7 +318,6 @@ fn rep_const_bool{}(wv:usz, x:*u64, r:*u64, rlen:usz) : u1 = {
} else { } else {
rep_const_bool_odd{wv, x, r, nw} rep_const_bool_odd{wv, x, r, nw}
} }
1
} }
def rep_const_bool_div8{wv, x, r, nw} = { # wv in 2,4,8 def rep_const_bool_div8{wv, x, r, nw} = { # wv in 2,4,8