Factor (8×k)/bool as bit-replicate, then byte-replicate
This commit is contained in:
parent
fc1265b3f2
commit
bf69705c82
@ -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) }
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user