2010-12-12 66 views
3

从100,000字节的数组开始,其中只有每个字节中的低6位具有有用数据。我需要尽可能快地将这些数据打包成一个75,000字节的数组,以保持数据的顺序。尽可能快地将数据打包到数组中

unsigned int Joinbits(unsigned int in) {} 
+3

6位* 4 = 24位= 3个字节。编写代码一次处理四个字节,每个都做'正确的事情',并且你将成为赢家。 – 2010-12-12 23:55:15

+0

什么是您的系统字大小?你的系统处理器是什么? “尽可能快”将取决于系统特定的行为,例如哪些操作导致最平行和最少量的代码。 – 2010-12-12 23:58:45

+0

鉴于您的一些6位值将与结果中的字节边界相重叠,所以在此处会引入字节序。你想要什么endian? – 2010-12-13 00:01:38

回答

4
// 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; 
    } 
} 

将失败。 完全便携。读取4次输入字节6次,因此读取效率低于50%,但处理器缓存和编译器优化程序可能有所帮助。尝试使用变量保存读取可能会适得其反,只有实际的测量结果才能说明问题。

0
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

只适用于int可能与任何对齐的平台。 – 2010-12-13 00:46:31

+0

由于未对齐,大多数平台上的Segfault都会发生。 – Yttrill 2010-12-13 00:46:48

+1

大多数平台?当然你的意思是一些平台。如果您将Windows作为平台。 – TonyK 2010-12-13 00:57:18

0

这是C,我不知道C++。并且可能充满了错误,而且绝不是最快的方式,它可能并不快。但是我想要去一趟,因为这似乎是一个有趣的挑战,所以请让我知道我做错了什么! :如果输入长度不是整除4.假设输入的高2位是零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

首先,您应该在对它们进行位操作时专门使用无符号字符和整数。而你的两个最终作业将不起作用,它们只在位置i和i + 4处分配字节。 – Yttrill 2010-12-13 00:51:52

+0

另外,你丢失了解压[]的最后四个字节。 – TonyK 2010-12-13 00:55:56

+0

您想要将4个输入字节打包为3个输出字节。你目前正在打包5到4,然后尝试打包3到2,他们不适合。另外,将一个int分配给一个char数组并不会用int数据填充4个连续的数组槽(甚至假设'sizeof(int)== 4',这在C或C++中是不能保证的)。它将int转换为char并将其分配到一个指定的槽中。 – 2010-12-13 01:12:13