/* Here we compress the data in blocks of 128 integers with varying bit width */ int varying_bit_width_demo() { size_t nn = 128 * 2; uint32_t * datainn = malloc(nn * sizeof(uint32_t)); uint8_t * buffern = malloc(nn * sizeof(uint32_t) + nn / SIMDBlockSize); uint32_t * backbuffern = malloc(nn * sizeof(uint32_t)); size_t k, compsize; printf("== varying bit-width demo\n"); for(k=0;k<nn;++k){ datainn[k] = rand() % (k + 1); } compsize = varying_bit_width_compress(datainn,nn,buffern); printf("encoded size: %u (original size: %u)\n", (unsigned)compsize, (unsigned)(nn * sizeof(uint32_t))); for (k = 0; k * SIMDBlockSize < nn; ++k) { uint32_t b = *buffern; buffern++; simdunpack((const __m128i *)buffern, backbuffern + k * SIMDBlockSize, b); buffern += b * sizeof(__m128i); } for (k = 0; k < nn; ++k){ if(backbuffern[k] != datainn[k]) { printf("bug\n"); return -1;} } printf("Code works!\n"); return 0; }
int test() { int N = 5000 * SIMDBlockSize, gap; __m128i * buffer = malloc(SIMDBlockSize * sizeof(uint32_t)); uint32_t * datain = malloc(N * sizeof(uint32_t)); uint32_t * backbuffer = malloc(SIMDBlockSize * sizeof(uint32_t)); for (gap = 1; gap <= 387420489; gap *= 3) { int k; printf(" gap = %u \n", gap); for (k = 0; k < N; ++k) datain[k] = k * gap; for (k = 0; k * SIMDBlockSize < N; ++k) { /* First part works for general arrays (sorted or unsorted) */ int j; /* we compute the bit width */ const uint32_t b = maxbits(datain + k * SIMDBlockSize); /* we read 128 integers at "datain + k * SIMDBlockSize" and write b 128-bit vectors at "buffer" */ simdpackwithoutmask(datain + k * SIMDBlockSize, buffer, b); /* we read back b1 128-bit vectors at "buffer" and write 128 integers at backbuffer */ simdunpack(buffer, backbuffer, b);/* uncompressed */ for (j = 0; j < SIMDBlockSize; ++j) { if (backbuffer[j] != datain[k * SIMDBlockSize + j]) { printf("bug in simdpack\n"); return -2; } } { /* next part assumes that the data is sorted (uses differential coding) */ uint32_t offset = 0; /* we compute the bit width */ const uint32_t b1 = simdmaxbitsd1(offset, datain + k * SIMDBlockSize); /* we read 128 integers at "datain + k * SIMDBlockSize" and write b1 128-bit vectors at "buffer" */ simdpackwithoutmaskd1(offset, datain + k * SIMDBlockSize, buffer, b1); /* we read back b1 128-bit vectors at "buffer" and write 128 integers at backbuffer */ simdunpackd1(offset, buffer, backbuffer, b1); for (j = 0; j < SIMDBlockSize; ++j) { if (backbuffer[j] != datain[k * SIMDBlockSize + j]) { printf("bug in simdpack d1\n"); return -3; } } offset = datain[k * SIMDBlockSize + SIMDBlockSize - 1]; } } } free(buffer); free(datain); free(backbuffer); printf("Code looks good.\n"); return 0; }
unsigned char *simdunpackn(uint32_t *in, uint32_t n, uint32_t b, uint32_t *out) { uint32_t k, *out_; for(out_ = out + n; out + 128 <= out_; out += 128, in += 4 * b) simdunpack((const __m128i *)in, out, b); return (unsigned char *)in; }