TurboPFor: Variable byte encode/decode

This commit is contained in:
x
2019-12-21 14:06:33 +01:00
parent 3c3972bc28
commit a2a41e201b

80
vint.c
View File

@ -98,10 +98,10 @@ unsigned char *TEMPLATE2(vbdec, USIZE)(unsigned char *__restrict in, unsigned n
#define VBE(_i_) TEMPLATE2(_vbget, USIZE)(in, x, op[_i_] = x) #define VBE(_i_) TEMPLATE2(_vbget, USIZE)(in, x, op[_i_] = x)
for(op = out; op != out+(n&~(UN-1)); op += UN) { for(op = out; op != out+(n&~(UN-1)); op += UN) {
VBE(0); VBE(1); VBE(2); VBE(3); VBE(0); VBE(1); VBE(2); VBE(3);
#if UN > 4 #if UN > 4
VBE(4); VBE(5); VBE(6); VBE(7); VBE(4); VBE(5); VBE(6); VBE(7);
#endif #endif
PREFETCH(in+16*USIZE, 0); PREFETCH(in+16*USIZE, 0);
} }
while(op != out+n) while(op != out+n)
TEMPLATE2(_vbget, USIZE)(in, x, *op++ = x ); TEMPLATE2(_vbget, USIZE)(in, x, *op++ = x );
@ -114,15 +114,15 @@ unsigned char *TEMPLATE2(vbenc, USIZE)(uint_t *__restrict in, unsigned n, unsign
unsigned char *op = out; unsigned char *op = out;
#define VBD(_i_) x = ip[_i_]; TEMPLATE2(_vbput, USIZE)(op, x, ;); #define VBD(_i_) x = ip[_i_]; TEMPLATE2(_vbput, USIZE)(op, x, ;);
for(ip = in; ip != in+(n&~(UN-1)); ip += UN) { PREFETCH(ip+USIZE*8, 0); for(ip = in; ip != in+(n&~(UN-1)); ip += UN) { PREFETCH(ip+USIZE*8, 0);
VBD(0); VBD(1); VBD(2); VBD(3); VBD(0); VBD(1); VBD(2); VBD(3);
#if UN > 4 #if UN > 4
VBD(4); VBD(5); VBD(6); VBD(7); VBD(4); VBD(5); VBD(6); VBD(7);
#endif #endif
} }
while(ip != in+n) { while(ip != in+n) {
x = *ip++; x = *ip++;
TEMPLATE2(_vbput, USIZE)(op, x, ;); TEMPLATE2(_vbput, USIZE)(op, x, ;);
} }
OVERFLOWE(in,n,out,op,VB_MAX+1); OVERFLOWE(in,n,out,op,VB_MAX+1);
@ -137,7 +137,7 @@ uint_t TEMPLATE2(vbgetx, USIZE)(unsigned char *__restrict in, unsigned idx) {
if(*in == 255) if(*in == 255)
return TEMPLATE2(ctou, USIZE)(in+1+idx*(USIZE/8)); return TEMPLATE2(ctou, USIZE)(in+1+idx*(USIZE/8));
for(ip = in,i = 0; i <= idx; i++) for(ip = in,i = 0; i <= idx; i++)
ip += TEMPLATE2(_vbvlen, USIZE)(*ip); ip += TEMPLATE2(_vbvlen, USIZE)(*ip);
TEMPLATE2(_vbget, USIZE)(in, x, ;); TEMPLATE2(_vbget, USIZE)(in, x, ;);
return x; return x;
} }
@ -148,12 +148,12 @@ uint_t TEMPLATE2(vbgetx, USIZE)(unsigned char *__restrict in, unsigned idx) {
uint_t x; uint_t x;
if(*in == 255) { if(*in == 255) {
for(ip = (*_ip==in)?in:*ip; ip < in+n; ip+USIZE/8) { for(ip = (*_ip==in)?in:*ip; ip < in+n; ip+USIZE/8) {
TEMPLATE2(_vbget, USIZE)(ip, x, ;); TEMPLATE2(_vbget, USIZE)(ip, x, ;);
if((x = TEMPLATE2(ctou, USIZE)(ip)) == key) break; if((x = TEMPLATE2(ctou, USIZE)(ip)) == key) break;
} }
} else for(ip = *_ip,i=idx; i < n; i++) { } else for(ip = *_ip,i=idx; i < n; i++) {
TEMPLATE2(_vbget, USIZE)(ip, x, ;); TEMPLATE2(_vbget, USIZE)(ip, x, ;);
if(x == key) break; if(x == key) break;
} }
*_ip = ip; *_ip = ip;
return i; return i;
@ -180,7 +180,7 @@ unsigned char *TEMPLATE2(vbdddec, USIZE)(unsigned char *__restrict in, unsigned
unsigned char *bp=in; in+=(n+7)/8; unsigned char *bp=in; in+=(n+7)/8;
for(op = out; op != out+(n&~(8-1)); op+=8,bp++) { for(op = out; op != out+(n&~(8-1)); op+=8,bp++) {
if(!bp[0]) { op[0]=(start+=pd); op[1]=(start+=pd); op[2]=(start+=pd); op[3]=(start+=pd); op[4]=(start+=pd); op[5]=(start+=pd); op[6]=(start+=pd); op[7]=(start+=pd); continue; } if(!bp[0]) { op[0]=(start+=pd); op[1]=(start+=pd); op[2]=(start+=pd); op[3]=(start+=pd); op[4]=(start+=pd); op[5]=(start+=pd); op[6]=(start+=pd); op[7]=(start+=pd); continue; }
VBDDD(0); VBDDD(1); VBDDD(2); VBDDD(3); VBDDD(4); VBDDD(5); VBDDD(6); VBDDD(7); PREFETCH(in+16*USIZE, 0); VBDDD(0); VBDDD(1); VBDDD(2); VBDDD(3); VBDDD(4); VBDDD(5); VBDDD(6); VBDDD(7); PREFETCH(in+16*USIZE, 0);
} }
for(p=op; p != out+n; p++) VBDDD(p-op); for(p=op; p != out+n; p++) VBDDD(p-op);
return in; return in;
@ -194,7 +194,7 @@ unsigned char *TEMPLATE2(vbzenc, USIZE)(uint_t *__restrict in, unsigned n, unsig
#define VBZE { v = TEMPLATE2(zigzagenc, USIZE)((TEMPLATE3(int, USIZE, _t))(*ip)-(TEMPLATE3(int, USIZE, _t))start); start=*ip++; TEMPLATE2(_vbput, USIZE)(op, v, ;); } #define VBZE { v = TEMPLATE2(zigzagenc, USIZE)((TEMPLATE3(int, USIZE, _t))(*ip)-(TEMPLATE3(int, USIZE, _t))start); start=*ip++; TEMPLATE2(_vbput, USIZE)(op, v, ;); }
for(ip = in; ip != in+(n&~(UN-1)); ) { VBZE;VBZE;VBZE;VBZE; } for(ip = in; ip != in+(n&~(UN-1)); ) { VBZE;VBZE;VBZE;VBZE; }
while(ip != in+n) VBZE; //OVERFLOWE(in,n,out,op); while(ip != in+n) VBZE; //OVERFLOWE(in,n,out,op);
return op; return op;
} }
#undef VBZE #undef VBZE
@ -204,10 +204,10 @@ unsigned char *TEMPLATE2(vbzdec, USIZE)(unsigned char *__restrict in, unsigned n
#define VBZD { TEMPLATE2(_vbget, USIZE)(in, x, ;); *op++ = (start += TEMPLATE2(zigzagdec, USIZE)(x)); } #define VBZD { TEMPLATE2(_vbget, USIZE)(in, x, ;); *op++ = (start += TEMPLATE2(zigzagdec, USIZE)(x)); }
for(op = out; op != out+(n&~(UN-1)); ) { VBZD; VBZD; VBZD; VBZD; for(op = out; op != out+(n&~(UN-1)); ) { VBZD; VBZD; VBZD; VBZD;
#if UN > 4 #if UN > 4
VBZD; VBZD; VBZD; VBZD; VBZD; VBZD; VBZD; VBZD;
#endif #endif
PREFETCH(in+16*USIZE, 0); PREFETCH(in+16*USIZE, 0);
} }
while(op != out+n) VBZD; while(op != out+n) VBZD;
@ -221,7 +221,7 @@ uint_t TEMPLATE2(vbzgetx, USIZE)(unsigned char *__restrict in, unsigned idx, ui
uint_t x; uint_t x;
for(ip = in,i = 0; i <= idx; i++) { for(ip = in,i = 0; i <= idx; i++) {
TEMPLATE2(_vbget, USIZE)(ip, x, ;); TEMPLATE2(_vbget, USIZE)(ip, x, ;);
start += x+VDELTA; start += x+VDELTA;
} }
return start; return start;
@ -232,8 +232,8 @@ unsigned TEMPLATE2(vbzgeteq, USIZE)(unsigned char **__restrict in, unsigned n, u
unsigned char *ip; unsigned char *ip;
uint_t x; uint_t x;
for(ip = *in,i=idx; i < n; i++) { for(ip = *in,i=idx; i < n; i++) {
TEMPLATE2(_vbget, USIZE)(ip, x, ;); TEMPLATE2(_vbget, USIZE)(ip, x, ;);
if((start += x+VDELTA) == key) if((start += x+VDELTA) == key)
break; break;
} }
*in = ip; *in = ip;
@ -246,7 +246,7 @@ unsigned char *TEMPLATE2(vbxenc, USIZE)(uint_t *__restrict in, unsigned n, unsig
#define VBXE { v = (*ip)^start; start=*ip++; TEMPLATE2(_vbput, USIZE)(op, v, ;); } #define VBXE { v = (*ip)^start; start=*ip++; TEMPLATE2(_vbput, USIZE)(op, v, ;); }
for(ip = in; ip != in+(n&~(UN-1)); ) { VBXE;VBXE;VBXE;VBXE; } for(ip = in; ip != in+(n&~(UN-1)); ) { VBXE;VBXE;VBXE;VBXE; }
while(ip != in+n) VBXE; //OVERFLOWE(in,n,out,op); while(ip != in+n) VBXE; //OVERFLOWE(in,n,out,op);
return op; return op;
} }
#undef VBZE #undef VBZE
@ -256,10 +256,10 @@ unsigned char *TEMPLATE2(vbxdec, USIZE)(unsigned char *__restrict in, unsigned n
#define VBXD { TEMPLATE2(_vbget, USIZE)(in, x, ;); *op++ = (start ^= x); } #define VBXD { TEMPLATE2(_vbget, USIZE)(in, x, ;); *op++ = (start ^= x); }
for(op = out; op != out+(n&~(UN-1)); ) { VBXD; VBXD; VBXD; VBXD; for(op = out; op != out+(n&~(UN-1)); ) { VBXD; VBXD; VBXD; VBXD;
#if UN > 4 #if UN > 4
VBXD; VBXD; VBXD; VBXD; VBXD; VBXD; VBXD; VBXD;
#endif #endif
PREFETCH(in+16*USIZE, 0); PREFETCH(in+16*USIZE, 0);
} }
while(op != out+n) VBXD; while(op != out+n) VBXD;
@ -273,7 +273,7 @@ uint_t TEMPLATE2(vbxgetx, USIZE)(unsigned char *__restrict in, unsigned idx, ui
uint_t x; uint_t x;
for(ip = in,i = 0; i <= idx; i++) { for(ip = in,i = 0; i <= idx; i++) {
TEMPLATE2(_vbget, USIZE)(ip, x, ;); TEMPLATE2(_vbget, USIZE)(ip, x, ;);
start ^= x; start ^= x;
} }
return start; return start;
@ -284,8 +284,8 @@ unsigned TEMPLATE2(vbxgeteq, USIZE)(unsigned char **__restrict in, unsigned n, u
unsigned char *ip; unsigned char *ip;
uint_t x; uint_t x;
for(ip = *in,i=idx; i < n; i++) { for(ip = *in,i=idx; i < n; i++) {
TEMPLATE2(_vbget, USIZE)(ip, x, ;); TEMPLATE2(_vbget, USIZE)(ip, x, ;);
if((start ^= x) == key) if((start ^= x) == key)
break; break;
} }
*in = ip; *in = ip;
@ -304,7 +304,7 @@ unsigned char *TEMPLATE2(VBDENC, USIZE)(uint_t *__restrict in, unsigned n, unsig
#endif #endif
#define VBDE { v = ip[0]-start-VDELTA; start = *ip++; TEMPLATE2(_vbput, USIZE)(op, v, ;); b |= (v /*^ x*/); } #define VBDE { v = ip[0]-start-VDELTA; start = *ip++; TEMPLATE2(_vbput, USIZE)(op, v, ;); b |= (v /*^ x*/); }
for(ip = in; ip != in + (n&~(UN-1)); ) { VBDE; VBDE; VBDE; VBDE; for(ip = in; ip != in + (n&~(UN-1)); ) { VBDE; VBDE; VBDE; VBDE;
#if UN > 4 #if UN > 4
VBDE; VBDE; VBDE; VBDE; VBDE; VBDE; VBDE; VBDE;
#endif #endif
} }
@ -328,39 +328,39 @@ unsigned char *TEMPLATE2(VBDDEC, USIZE)(unsigned char *__restrict in, unsigned n
if(in[0] == VB_MX) { if(in[0] == VB_MX) {
in++; in++;
#if (defined(__SSE2__) || defined(__ARM_NEON)) && USIZE == 32 #if (defined(__SSE2__) || defined(__ARM_NEON)) && USIZE == 32
#if VDELTA == 0 #if VDELTA == 0
if(n) TEMPLATE2(BITZERO, USIZE)(out, n, start); if(n) TEMPLATE2(BITZERO, USIZE)(out, n, start);
#else #else
if(n) TEMPLATE2(BITDIZERO,USIZE)(out, n, start, VDELTA); if(n) TEMPLATE2(BITDIZERO,USIZE)(out, n, start, VDELTA);
#endif #endif
#else #else
#if VDELTA == 0 #if VDELTA == 0
for(x = 0; x < n; x++) out[x] = start; for(x = 0; x < n; x++) out[x] = start;
#else #else
for(x = 0; x < n; x++) out[x] = start+x*VDELTA; for(x = 0; x < n; x++) out[x] = start+x*VDELTA;
#endif #endif
#endif #endif
return in; return in;
} }
#if 0 //USIZE < 64 #if 0 //USIZE < 64
else if(in[0] == VB_MAX-2) { in++; else if(in[0] == VB_MAX-2) { in++;
uint_t z; uint_t z;
TEMPLATE2(_vbget, USIZE)(in, z, ;); TEMPLATE2(_vbget, USIZE)(in, z, ;);
#if VDELTA == 0 #if VDELTA == 0
for(x = 0; x < n; x++) out[x] = start+z; for(x = 0; x < n; x++) out[x] = start+z;
#else #else
for(x = 0; x < n; x++) out[x] = start+x+z; for(x = 0; x < n; x++) out[x] = start+x+z;
#endif #endif
return in; return in;
} }
#endif #endif
#define VBDD(i) { TEMPLATE2(_vbget, USIZE)(in, x, x+=VDELTA); op[i] = (start += x); } #define VBDD(i) { TEMPLATE2(_vbget, USIZE)(in, x, x+=VDELTA); op[i] = (start += x); }
for(op = out; op != out+(n&~(UN-1)); op+=UN) { for(op = out; op != out+(n&~(UN-1)); op+=UN) {
VBDD(0); VBDD(1); VBDD(2); VBDD(3); VBDD(0); VBDD(1); VBDD(2); VBDD(3);
#if UN > 4 #if UN > 4
VBDD(4); VBDD(5); VBDD(6); VBDD(7); VBDD(4); VBDD(5); VBDD(6); VBDD(7);
#endif #endif
PREFETCH(in+16*USIZE, 0); PREFETCH(in+16*USIZE, 0);
} }
for(;op != out+n;op++) VBDD(0); for(;op != out+n;op++) VBDD(0);
return in; return in;
@ -378,7 +378,7 @@ uint_t TEMPLATE2(VBDGETX, USIZE)(unsigned char *__restrict in, unsigned idx, ui
if(u & 1) return start + VDELTA; if(u & 1) return start + VDELTA;
#endif #endif
for(ip = in; i <= idx; i++) { for(ip = in; i <= idx; i++) {
TEMPLATE2(_vbget, USIZE)(ip, x, ;); TEMPLATE2(_vbget, USIZE)(ip, x, ;);
start += x+VDELTA; start += x+VDELTA;
} }
return start; return start;
@ -396,8 +396,8 @@ unsigned TEMPLATE2(VBDGETGEQ, USIZE)(unsigned char **__restrict in, unsigned n,
} }
#endif #endif
for(ip = *in; i < n; i++) { for(ip = *in; i < n; i++) {
TEMPLATE2(_vbget, USIZE)(ip, x, ;); TEMPLATE2(_vbget, USIZE)(ip, x, ;);
if((start += x+VDELTA) == *key) if((start += x+VDELTA) == *key)
break; break;
} }
*in = ip; *in = ip;