2010-12-12 57 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

相關問題