Perpustakaan SIMDComp
Pustaka C sederhana untuk mengompresi daftar bilangan bulat menggunakan pengepakan biner dan instruksi SIMD. Asumsinya adalah Anda memiliki daftar bilangan bulat 32-bit yang sebagian besarnya kecil, atau daftar bilangan bulat 32-bit yang perbedaan antara bilangan bulat yang berurutan kecil. Tidak ada perangkat lunak yang mampu mengompresi array angka acak 32-bit dengan andal.
Pustaka ini dapat memecahkan kode setidaknya 4 miliar bilangan bulat terkompresi per detik di sebagian besar prosesor desktop atau laptop. Artinya, ia dapat mendekompresi data dengan kecepatan 15 GB/s. Ini jauh lebih cepat daripada codec umum seperti gzip, LZO, Snappy, atau LZ4.
Pada prosesor Intel Skylake, ia dapat memecahkan kode bilangan bulat dengan kecepatan 0,3 siklus per bilangan bulat, yang dapat dengan mudah diterjemahkan menjadi lebih dari 8 miliar bilangan bulat yang didekodekan per detik.
Pustaka ini adalah bagian dari daftar sumber daya C yang Luar Biasa.
Kontributor: Daniel Lemire, Nathan Kurz, Christoph Rupp, Anatol Belski, Nick White dan lainnya
Untuk apa?
Ini adalah perpustakaan tingkat rendah untuk kompresi bilangan bulat cepat. Secara desain, ini tidak menentukan format terkompresi. Terserah kepada pengguna (canggih) untuk membuat format terkompresi.
Ini digunakan oleh:
- ditingkatkanb
- AcaraQL
- Pencarian Manticore
Persyaratan
- Prosesor Anda harus mendukung SSE4.1 (Ini didukung oleh sebagian besar prosesor Intel dan AMD yang dirilis sejak 2008.)
- Dimungkinkan untuk membuat bagian inti kode jika prosesor Anda mendukung SSE2 (Pentium4 atau lebih baik)
- Kompiler yang sesuai dengan C99 (diasumsikan GCC)
- Distribusi mirip Linux diasumsikan oleh makefile
Untuk versi C biasa yang tidak menggunakan instruksi SIMD, lihat https://github.com/lemire/LittleIntPacker
Penggunaan
Kompresi bekerja pada blok yang terdiri dari 128 bilangan bulat.
Untuk contoh kerja lengkap, lihat example.c (Anda dapat membuatnya dan menjalankannya dengan "make example; ./example").
- Daftar bilangan bulat dalam urutan acak.
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
Meskipun 128 bilangan bulat 32-bit dibaca, hanya b kata 128-bit yang ditulis. Jadi, perbandingan kompresinya adalah 32/b.
- Daftar bilangan bulat yang diurutkan.
Kami menggunakan pengkodean diferensial: kami menyimpan selisih antara bilangan bulat yang berurutan. Untuk tujuan ini, kita memerlukan nilai awal (disebut offset).
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
Contoh umum untuk array dengan panjang sembarang:
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 ;
}
- Kerangka Acuan
Kami juga memiliki fungsi frame-of-reference (FOR) (lihat header simdfor.h). Mereka bekerja seperti rutinitas pengepakan bit, tetapi tidak menggunakan pengkodean diferensial sehingga memungkinkan pencarian lebih cepat dalam beberapa kasus, dengan mengorbankan kompresi.
Pengaturan
membuat tes
dan jika Anda berani:
buat instal
Pergi
Jika Anda pengguna go, ada folder "go" di mana Anda akan menemukan demo sederhana.
Perpustakaan lainnya
- Kompresi bilangan bulat cepat di Go: https://github.com/ronanh/intcomp
- Algoritma Bitpacking Cepat: Port karat simdcomp https://github.com/quickwit-oss/bitpacking
- SIMDCompressionAndIntersection: Pustaka C++ untuk mengompresi dan memotong daftar bilangan bulat yang diurutkan menggunakan instruksi SIMD https://github.com/lemire/SIMDCompressionAndIntersection
- Pustaka FastPFOR C++ : Kompresi bilangan bulat cepat https://github.com/lemire/FastPFor
- Pengkodean kamus berkinerja tinggi https://github.com/lemire/dictionary
- LittleIntPacker: Pustaka C untuk mengemas dan membongkar array pendek bilangan bulat secepat mungkin https://github.com/lemire/LittleIntPacker
- StreamVByte: Kompresi bilangan bulat cepat di C menggunakan codec StreamVByte https://github.com/lemire/streamvbyte
- MaskedVByte: Dekoder cepat untuk bilangan bulat terkompresi VByte https://github.com/lemire/MaskedVByte
- CSharpFastPFOR: pustaka kompresi bilangan bulat AC# https://github.com/Genbox/CSharpFastPFOR
- JavaFastPFOR: Pustaka kompresi bilangan bulat Java https://github.com/lemire/JavaFastPFOR
- Pengkodean: Pustaka Kompresi Integer untuk Go https://github.com/zhenjl/encoding
- FrameOfReference adalah pustaka C++ yang didedikasikan untuk kompresi frame-of-reference (FOR): https://github.com/lemire/FrameOfReference
- libvbyte: Implementasi cepat untuk kompresi integer varbyte 32bit/64bit https://github.com/cruppstahl/libvbyte
- TurboPFor adalah perpustakaan C yang menawarkan banyak optimasi menarik. Layak untuk dicoba! (Lisensi GPL) https://github.com/powturbo/TurboPFor
- Oroch adalah perpustakaan C++ yang menawarkan API yang dapat digunakan (lisensi MIT) https://github.com/ademkov/Oroch
Bahasa pemrograman lainnya
- Ada bungkus untuk Julia.
- Ada port Rust.
Referensi
- Daniel Lemire, Nathan Kurz, Christoph Rupp, Stream VByte: Kompresi Integer Berorientasi Byte Lebih Cepat, Surat Pemrosesan Informasi, Surat Pemrosesan Informasi 130, Februari 2018, Halaman 1-6https://arxiv.org/abs/1709.08990
- Jianguo Wang, Chunbin Lin, Yannis Papakonstantinou, Steven Swanson, Studi Eksperimental Kompresi Bitmap vs. Kompresi Daftar Terbalik, SIGMOD 2017 http://db.ucsd.edu/wp-content/uploads/2017/03/sidm338-wangA. pdf
- P. Damme, D. Habich, J. Hildebrandt, W. Lehner, Algoritma Kompresi Data Ringan: Survei Eksperimental (Eksperimen dan Analisis), EDBT 2017 http://openproceedings.org/2017/conf/edbt/paper-146. pdf
- P. Damme, D. Habich, J. Hildebrandt, W. Lehner, Wawasan Evaluasi Komparatif Algoritma Kompresi Data Ringan, EDBT 2017 http://openproceedings.org/2017/conf/edbt/paper-414.pdf
- Daniel Lemire, Leonid Boytsov, Nathan Kurz, Kompresi SIMD dan Persimpangan Integer Terurut, Praktik & Pengalaman Perangkat Lunak 46 (6) 2016. http://arxiv.org/abs/1401.6399
- Daniel Lemire dan Leonid Boytsov, Menguraikan miliaran bilangan bulat per detik melalui vektorisasi, Praktik & Pengalaman Perangkat Lunak 45 (1), 2015. http://arxiv.org/abs/1209.2137 http://onlinelibrary.wiley.com/doi/10.1002 /spe.2203/abstrak
- Jeff Plaisance, Nathan Kurz, Daniel Lemire, Decoding VByte Vektor, Simposium Internasional tentang Algoritma Web 2015, 2015. http://arxiv.org/abs/1503.07387
- Wayne Xin Zhao, Xudong Zhang, Daniel Lemire, Dongdong Shan, Jian-Yun Nie, Hongfei Yan, Ji-Rong Wen, Pendekatan Umum Berbasis SIMD untuk Mempercepat Algoritma Kompresi, Transaksi ACM pada Sistem Informasi 33 (3), 2015. http ://arxiv.org/abs/1502.01916
- TD Wu, Teknik Bitpacking untuk mengindeks genom: I. Tabel hash, Algoritma untuk Biologi Molekuler 11 (5), 2016. http://almob.biomedcentral.com/articles/10.1186/s13015-016-0069-5