Fast skip ahead for blocks of equal values in i8 and i16 /⁼

This commit is contained in:
Marshall Lochbaum 2024-11-17 10:16:48 -05:00
parent 7baddcabc2
commit 33ae8744f5

View File

@ -32,8 +32,18 @@ fn count{T if T<=i16}(tab:*u16, ov:*u16, xp:*void, n:u64, min_allowed:T) : T = {
# Also record number of differences dc
# (double-counts at index vec but it doesn't need to be exact)
xv := *V~~x
jv := load{xv}; mv := jv; dc := -(jv != load{*V~~(x+1)})
@for (xv, xp in *V~~(x-1) over _ from 1 to b) {
jv := load{xv}; mv := jv
ne := jv != load{*V~~(x+1)}; dc := -ne
# Quickly skip ahead if initial values are all equal
a:u64 = 1
if (not homAny{ne} and b>=4) {
def eq_k{k} = homAll{tree_fold{&, @unroll(x in xv+a over k) x==jv}}
def skip_eq{k} = if (eq_k{k}) { a=2*k; skip_eq{2*k} }
def skip_eq{k==4} = while (a<=b-k and eq_k{k}) a+=k
skip_eq{1}
}
# Now start analysis
@for (xv, xp in *V~~(x-1) over _ from a to b) {
jv = min{jv, xv}; mv = max{mv, xv}
dc -= xp != xv
}