一個簡單的 C 庫,用於使用二進位打包和 SIMD 指令壓縮整數列表。假設您有一個 32 位元整數列表,其中大多數整數都很小,或者有一個 32 位元整數列表,其中連續整數之間的差異很小。沒有軟體能夠可靠地壓縮 32 位元隨機數數組。
在大多數桌上型電腦或筆記型電腦處理器上,該程式庫每秒可以解碼至少 40 億個壓縮整數。即能夠以15GB/s的速率解壓縮資料。這比 gzip、LZO、Snappy 或 LZ4 等通用編解碼器快得多。
在 Skylake Intel 處理器上,它可以以每個整數 0.3 個週期的速率解碼整數,這可以輕鬆轉換為每秒解碼超過 8 個數十億個整數。
該庫是 Awesome C C 資源清單的一部分。
貢獻者:Daniel Lemire、Nathan Kurz、Christoph Rupp、Anatol Belski、Nick White 等
這是一個用於快速整數壓縮的低階庫。根據設計,它沒有定義壓縮格式。由(複雜的)使用者建立壓縮格式。
它的使用者:
不使用 SIMD 指令的純 C 版本,請參閱 https://github.com/lemire/LittleIntPacker
壓縮適用於 128 個整數的區塊。
有關完整的工作範例,請參閱 example.c(您可以使用“make example; ./example”建置並執行它)。
const uint32_t b = maxbits ( datain ); // computes bit width
simdpackwithoutmask ( datain , buffer , b ); //compressed to buffer, compressing 128 32-bit integers down to b*32 bytes
simdunpack ( buffer , backbuffer , b ); //uncompressed to backbuffer
當讀取 128 個 32 位元整數時,僅寫入 b 個 128 位元字。因此,壓縮比為32/b。
我們使用差分編碼:我們儲存連續整數之間的差異。為此,我們需要一個初始值(稱為偏移量)。
uint32_t offset = 0 ;
uint32_t b1 = simdmaxbitsd1 ( offset , datain ); // bit width
simdpackwithoutmaskd1 ( offset , datain , buffer , b1 ); //compressing 128 32-bit integers down to b1*32 bytes
simdunpackd1 ( offset , buffer , backbuffer , b1 ); //uncompressed
任意長度數組的一般範例:
int compress_decompress_demo () {
size_t k , N = 9999 ;
__m128i * endofbuf ;
uint32_t * datain = malloc ( N * sizeof ( uint32_t ));
uint8_t * buffer ;
uint32_t * backbuffer = malloc ( N * sizeof ( uint32_t ));
uint32_t b ;
for ( k = 0 ; k < N ; ++ k ){ /* start with k=0, not k=1! */
datain [ k ] = k ;
}
b = maxbits_length ( datain , N );
buffer = malloc ( simdpack_compressedbytes ( N , b )); // allocate just enough memory
endofbuf = simdpack_length ( datain , N , ( __m128i * ) buffer , b );
/* compressed data is stored between buffer and endofbuf using (endofbuf-buffer)*sizeof(__m128i) bytes */
/* would be safe to do : buffer = realloc(buffer,(endofbuf-(__m128i *)buffer)*sizeof(__m128i)); */
simdunpack_length (( const __m128i * ) buffer , N , backbuffer , b );
for ( k = 0 ; k < N ; ++ k ){
if ( datain [ k ] != backbuffer [ k ]) {
printf ( "bugn" );
return -1 ;
}
}
return 0 ;
}
我們也有參考框架 (FOR) 函數(請參閱 simdfor.h 標頭)。它們的工作方式類似於位元打包例程,但不使用差分編碼,因此它們在某些情況下允許更快的搜索,但以壓縮為代價。
進行測試
如果你有膽量:
進行安裝
如果您是 go 用戶,有一個「go」資料夾,您可以在其中找到一個簡單的演示。