Pack data into arrays as quickly as possible

Im starting with an array of 100,000 bytes, where only the least 6 bits in each byte have useful data. I need to collect this data into an array of 75,000 bytes as quickly as possible, preserving the order of the data.

unsigned int Joinbits(unsigned int in) {}
+3
source share
3 answers
// 00111111 00111111 00111111 00111111
//   000000   001111   111122   222222
void pack6(
  register unsigned char o, 
  register unsigned char const *i, 
  unsigned char const *end
) 
{
  while(i!=end)
  {
    *o++ =  *i          << 2u | *(i+1) >> 4u; ++i;
    *o++ = (*i & 0xfu)  << 4u | *(i+1) >> 2u; ++i;
    *o++ = (*i & 0xfcu) << 6u | *(i+1)      ; i+=2;
  }
}

An error if the input length is not divisible by 4. It is assumed that the high 2 bits of the input are zero. Totally portable. Reads 4 bytes of input 6 times, so 50% inefficiency when reading, however, the processor cache and the compiler optimizer can help. Trying to use a variable to save what you read can be counterproductive, only the actual measurement can be displayed.

+4
source
for(int pos=0; pos<100000; pos+=4)
{
   *(int*)out = (in[0] & 0x3F) | ((in[1] & 0x3F)<<6) | ((in[2] & 0x3F)<<12) | ((in[3] & 0x3F)<<18);
   in += 4;
   out += 3;
}
0
source

This is C, I do not know C ++. And, probably, filled with errors, and this is far from the fastest way, it is probably not even fast. But I just wanted to leave, because it seemed to me that it was an interesting challenge to learn something, so please amaze me with what I did wrong !: D

unsigned char unpacked[100000];
unsigned int packed[75000 / 4];

for (int i = 0; i < (100000 / 6); i += 6) {
    unsigned int fourBytes = unpacked[i];
    fourBytes += unpacked[i + 1] << 6;
    fourBytes += unpacked[i + 2] << 12;
    fourBytes += unpacked[i + 3] << 18;
    fourBytes += unpacked[i + 4] << 24;
    fourBytes += unpacked[i + 5] << 30;

    unsigned short twoBytes = unpacked[i + 5] >> 2;
    twoBytes += unpacked[i + 6] << 4
    twoBytes += unpacked[i + 7] << 10;

    packed[i] = fourBytes;
    packed[i + 4] = twoBytes;
}
0
source

Source: https://habr.com/ru/post/1779895/


All Articles