Extend SIMD counting to i16 in addition to i8
This commit is contained in:
parent
e681f3c09a
commit
e24d0bac63
@ -97,9 +97,9 @@ extern void (*const si_scan_min_i16)(int16_t* v0,int16_t* v1,uint64_t v2);
|
|||||||
if (e==n) {break;} k=e; \
|
if (e==n) {break;} k=e; \
|
||||||
}
|
}
|
||||||
#define WRITE_SPARSE(T) WRITE_SPARSE_##T
|
#define WRITE_SPARSE(T) WRITE_SPARSE_##T
|
||||||
extern i8 (*const avx2_count_i8)(usz*, i8*, u64, i8);
|
extern i8 (*const simd_count_i8)(usz*, i8*, u64, i8);
|
||||||
#define SINGELI_COUNT_OR(T) \
|
#define SINGELI_COUNT_OR(T) \
|
||||||
if (1==sizeof(T)) avx2_count_i8(c0o, (i8*)xp, n, -128); else
|
if (1==sizeof(T)) simd_count_i8(c0o, (i8*)xp, n, -128); else
|
||||||
#else
|
#else
|
||||||
#define COUNT_THRESHOLD 16
|
#define COUNT_THRESHOLD 16
|
||||||
#define WRITE_SPARSE(T) \
|
#define WRITE_SPARSE(T) \
|
||||||
|
|||||||
@ -865,12 +865,10 @@ B slash_im(B t, B x) {
|
|||||||
usz m=1<<N; \
|
usz m=1<<N; \
|
||||||
if (xia < m/2) { \
|
if (xia < m/2) { \
|
||||||
IIND_INT(N) \
|
IIND_INT(N) \
|
||||||
} else SINGELI_COUNT_OR(N) { \
|
} else { \
|
||||||
TALLOC(usz, t, m); \
|
TALLOC(usz, t, SINGELI_COUNT_ALLOC); \
|
||||||
for (usz j=0; j<m/2; j++) t[j]=0; \
|
for (usz j=0; j<m/2; j++) t[j]=0; \
|
||||||
for (usz i=0; i<xia; i++) t[(u##N)xp[i]]++; \
|
SINGELI_COUNT(N) \
|
||||||
t[m/2]=xia; usz ria=0; for (u64 s=0; s<xia; ria++) s+=t[ria]; \
|
|
||||||
if (ria>m/2) thrM("/⁼: Argument cannot contain negative numbers"); \
|
|
||||||
i32* rp; r = m_i32arrv(&rp, ria); vfor (usz i=0; i<ria; i++) rp[i]=t[i]; \
|
i32* rp; r = m_i32arrv(&rp, ria); vfor (usz i=0; i<ria; i++) rp[i]=t[i]; \
|
||||||
TFREE(t); \
|
TFREE(t); \
|
||||||
r = num_squeeze(r); \
|
r = num_squeeze(r); \
|
||||||
@ -878,22 +876,22 @@ B slash_im(B t, B x) {
|
|||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
#if SINGELI_SIMD
|
#if SINGELI_SIMD
|
||||||
#define SINGELI_COUNT_OR(N) if (N==8) { \
|
#define SINGELI_COUNT_ALLOC m/2
|
||||||
TALLOC(usz, t, m/2); \
|
#define SINGELI_COUNT(N) \
|
||||||
for (usz j=0; j<m/2; j++) t[j]=0; \
|
i##N max = simd_count_i##N(t, xp, xia, 0); \
|
||||||
i8 max = avx2_count_i8(t, (i8*)xp, xia, 0); \
|
|
||||||
if (max < 0) thrM("/⁼: Argument cannot contain negative numbers"); \
|
if (max < 0) thrM("/⁼: Argument cannot contain negative numbers"); \
|
||||||
usz ria=max+1; \
|
usz ria=max+1;
|
||||||
i32* rp; r = m_i32arrv(&rp, ria); vfor (usz i=0; i<ria; i++) rp[i]=t[i]; \
|
|
||||||
TFREE(t); \
|
|
||||||
r = num_squeeze(r); \
|
|
||||||
} else
|
|
||||||
#else
|
#else
|
||||||
#define SINGELI_COUNT_OR(N)
|
#define SINGELI_COUNT_ALLOC m
|
||||||
|
#define SINGELI_COUNT(N) \
|
||||||
|
for (usz i=0; i<xia; i++) t[(u##N)xp[i]]++; \
|
||||||
|
t[m/2]=xia; usz ria=0; for (u64 s=0; s<xia; ria++) s+=t[ria]; \
|
||||||
|
if (ria>m/2) thrM("/⁼: Argument cannot contain negative numbers");
|
||||||
#endif
|
#endif
|
||||||
CASE_SMALL(8) CASE_SMALL(16)
|
CASE_SMALL(8) CASE_SMALL(16)
|
||||||
#undef CASE_SMALL
|
#undef CASE_SMALL
|
||||||
#undef SINGELI_COUNT_OR
|
#undef SINGELI_COUNT_ALLOC
|
||||||
|
#undef SINGELI_COUNT
|
||||||
case el_i32: { i32* xp = i32any_ptr(x); IIND_INT(32) r = num_squeeze(r); break; }
|
case el_i32: { i32* xp = i32any_ptr(x); IIND_INT(32) r = num_squeeze(r); break; }
|
||||||
#undef IIND_INT
|
#undef IIND_INT
|
||||||
case el_f64: {
|
case el_f64: {
|
||||||
|
|||||||
@ -3,14 +3,14 @@ include './vecfold'
|
|||||||
|
|
||||||
if_inline (hasarch{'SSE2'}) {
|
if_inline (hasarch{'SSE2'}) {
|
||||||
fn sum_vec{T}(v:T) = vfold{+, fold{+, mzip128{v, T**0}}}
|
fn sum_vec{T}(v:T) = vfold{+, fold{+, mzip128{v, T**0}}}
|
||||||
def fold_addw{v:T=[_](u8)} = sum_vec{T}(v)
|
def fold_addw{v:T=[_]E if E<=u16} = sum_vec{T}(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
def inc{ptr, ind, v} = store{ptr, ind, v + load{ptr, ind}}
|
def inc{ptr, ind, v} = store{ptr, ind, v + load{ptr, ind}}
|
||||||
def inc{ptr, ind} = inc{ptr, ind, 1}
|
def inc{ptr, ind} = inc{ptr, ind, 1}
|
||||||
|
|
||||||
# Write counts /⁼x to tab and return ⌈´x
|
# Write counts /⁼x to tab and return ⌈´x
|
||||||
fn count{T}(tab:*usz, x:*T, n:u64, min_allowed:T) : T = {
|
fn count{T}(tab:*usz, xp:*void, n:u64, min_allowed:T) : T = {
|
||||||
def vbits = arch_defvw
|
def vbits = arch_defvw
|
||||||
def vec = vbits/width{T}
|
def vec = vbits/width{T}
|
||||||
def uT = ty_u{T}
|
def uT = ty_u{T}
|
||||||
@ -18,6 +18,7 @@ fn count{T}(tab:*usz, x:*T, n:u64, min_allowed:T) : T = {
|
|||||||
def block = (2048*8) / vbits # Target vectors per block
|
def block = (2048*8) / vbits # Target vectors per block
|
||||||
def b_max = block + block/4 # Last block max length
|
def b_max = block + block/4 # Last block max length
|
||||||
assert{b_max < 1<<width{T}} # Don't overflow count in vector section
|
assert{b_max < 1<<width{T}} # Don't overflow count in vector section
|
||||||
|
x := *T~~xp
|
||||||
mx:T = min_allowed # Maximum of x
|
mx:T = min_allowed # Maximum of x
|
||||||
i:u64 = 0
|
i:u64 = 0
|
||||||
while (i < n) {
|
while (i < n) {
|
||||||
@ -111,4 +112,5 @@ def count_with_runs{V, vec, x, tab, r} = {
|
|||||||
bw * w
|
bw * w
|
||||||
}
|
}
|
||||||
|
|
||||||
export{'avx2_count_i8', count{i8}}
|
export{'simd_count_i8', count{i8}}
|
||||||
|
export{'simd_count_i16', count{i16}}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user