fast bit_cpy head & tail

This commit is contained in:
dzaima 2022-04-02 23:47:07 +03:00
parent 3e4b0e882d
commit a9331ef8f0
5 changed files with 85 additions and 15 deletions

View File

@ -234,6 +234,7 @@ static B unshare(B x) {
if (!isArr(x)) return x;
usz xia = a(x)->ia;
switch (v(x)->type) {
case t_bitarr: return taga(cpyBitArr(inc(x)));
case t_i8arr: return taga(cpyI8Arr (inc(x)));
case t_i16arr: return taga(cpyI16Arr(inc(x)));
case t_i32arr: return taga(cpyI32Arr(inc(x)));
@ -258,7 +259,15 @@ static B unshare(B x) {
}
}
B internalTemp_c1(B t, B x) { return x; }
B internalTemp_c1(B t, B x) {
#ifdef TEST_BITCPY
SGetU(x)
bit_cpy(bitarr_ptr(GetU(x,0)), o2s(GetU(x,1)), bitarr_ptr(GetU(x,2)), o2s(GetU(x,3)), o2s(GetU(x,4)));
#endif
return x;
}
B internalTemp_c2(B t, B w, B x) { dec(w); return x; }
B heapDump_c1(B t, B x) {

View File

@ -126,21 +126,40 @@ static void mut_copy(Mut* m, usz ms, B x, usz xs, usz l) { assert(isArr(x)); m->
static void bit_cpy(u64* r, usz rs, u64* x, usz xs, usz l) { // TODO rewrite this whole thing to be all fancy
u64 i = rs;
static void bit_cpy(u64* r, usz rs, u64* x, usz xs, usz l) {
u64 re = rs+(u64)l;
i64 d = (i64)xs-(i64)rs;
if (l>128) {
for (; i<re && (i&63)!=0; i++) bitp_set(r, i, bitp_get(x, i+d));
u64 ti = i>>6;
u64 ei = (re>>6) - 2;
i64 dp = d>>6;
u64 df = ((u64)d)&63u;
if (df==0) for (; ti<ei; ti++) r[ti] = x[ti+dp];
else for (; ti<ei; ti++) r[ti] = (x[ti+dp] >> df) | (x[ti+dp+1] << (64-df));
i = ti<<6;
u64 ti = rs>>6;
u64 ei = re>>6;
i64 dp = d>>6;
u64 df = ((u64)d)&63u;
#define RDF0 x[ti+dp]
#define RDFp ((x[ti+dp] >> df) | (x[ti+dp+1] << (64-df)))
#define READ (df==0? RDF0 : RDFp)
if (ti!=ei) {
if (rs&63) {
u64 m = (1ULL << (rs&63))-1;
r[ti] = (READ & ~m) | (r[ti] & m);
ti++;
}
if (df==0) for (; ti<ei; ti++) r[ti] = RDF0;
else for (; ti<ei; ti++) r[ti] = RDFp;
if (re&63) {
u64 m = (1ULL << (re&63))-1;
r[ti] = (READ & m) | (r[ti] & ~m);
}
} else if (rs!=re) {
assert(re!=0); // otherwise rs and re would be in different items, hitting the earlier ti!=ei; re!=0 is required for the mask to work
u64 m = ((1ULL << (rs&63))-1) ^ ((1ULL << (re&63))-1);
r[ti] = (READ & m) | (r[ti] & ~m);
}
for (; i<re; i++) bitp_set(r, i, bitp_get(x, i+d));
#undef READ
#undef RDFp
#undef RDF0
}
B vec_join(B w, B x); // consumes both

View File

@ -8,4 +8,5 @@ test/x86Cfgs.sh path/to/mlochbaum/BQN // run the test suite for x86-64-specific
test/moreCfgs.sh path/to/mlochbaum/BQN // run "2+2" in a bunch of configurations
./BQN test/cmp.bqn // fuzz-test scalar comparison functions =≠<≤>≥
./BQN test/equal.bqn // fuzz-test 𝕨≡𝕩
./BQN test/bitcpy.bqn // fuzz-test bit_cpy; requires a CBQN build with -DTEST_BITCPY
```

41
test/bitcpy.bqn Normal file
View File

@ -0,0 +1,41 @@
Temp, Type, Unshare, Squeeze, Info •internal
u •UnixTime@
# u ↩ 123
r •MakeRand •Show u
Do { 𝕊:
al 1+r.Range 500
aT al r.Range 2
a Squeeze aT
! a aT
! "i32arr" Type aT
! "bitarr" Type a
b Squeeze al r.Range 2
{ 𝕊:
bl r.Range 1+al
as r.Range 1+al-bl
bs r.Range 1+al-bl
i bl
exp ((bs+i)b)((as+i)) a
aC Unshare a
Temp aC, as, b, bs, bl
aC exp?
•Out "Fail:"
F {(¬ ·` ' '=)/ ' '˘˜ 64 '0'+𝕩}
•Out "Exp: "F exp
•Out "Got: "F aC
•Out "Inputs:"
•Out "r: "F a
•Out "rs: "•Repr as
•Out "x: "F b
•Out "xs: "•Repr bs
•Out "l: "•Repr bl
•Exit 1
;0
}@500 @
! a aT
}
@Do((•BQN¨•args)500) @

View File

@ -1,6 +1,6 @@
ListVariations, ClearRefs, Variation, Squeeze, Info •internal
u •UnixTime@
# u ↩ 1648896733
# u ↩ 123
r •MakeRand •Show u
@ -40,7 +40,7 @@ Do ← { 𝕊:
exp v = pa
b Squeeze v(p) a
(exp{𝕊:´a=b} at=4) TestVars ab
}100 @
}@100 @
}
@Do1000 @