SIMDComp ライブラリ
バイナリ パッキングと SIMD 命令を使用して整数のリストを圧縮するためのシンプルな C ライブラリ。前提として、ほとんどの整数が小さい 32 ビット整数のリスト、または連続する整数間の差が小さい 32 ビット整数のリストがあることが前提となります。 32 ビット乱数の配列を確実に圧縮できるソフトウェアはありません。
このライブラリは、ほとんどのデスクトップまたはラップトップ プロセッサで 1 秒あたり少なくとも 40 億の圧縮整数をデコードできます。つまり、15 GB/秒の速度でデータを解凍できます。これは、gzip、LZO、Snappy、LZ4 などの汎用コーデックよりも大幅に高速です。
Skylake Intel プロセッサでは、整数あたり 0.3 サイクルの速度で整数をデコードできます。これは、1 秒あたり 8 億を超える整数のデコードに容易に変換できます。
このライブラリは、C リソースの Awesome C リストの一部です。
寄稿者: Daniel Lemire、Nathan Kurz、Christoph Rupp、Anatol Belski、Nick White など
何のためにあるのでしょうか?
これは、高速整数圧縮のための低レベルのライブラリです。設計上、圧縮形式は定義されていません。圧縮形式を作成するかどうかは、(洗練された) ユーザーの責任です。
これは次のユーザーによって使用されます。
要件
- プロセッサーは SSE4.1 をサポートしている必要があります (2008 年以降にリリースされたほとんどの Intel および AMD プロセッサーでサポートされています)。
- プロセッサが SSE2 (Pentium4 以降) をサポートしている場合、コードのコア部分をビルドすることが可能です。
- C99準拠コンパイラ(GCCを想定)
- Linux 風のディストリビューションが Makefile によって想定されています
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」フォルダーに簡単なデモがあります。
その他の図書館
- Go での高速整数圧縮: https://github.com/ronanh/intcomp
- 高速ビットパッキング アルゴリズム: simdcomp の Rust ポート https://github.com/quickwit-oss/bitpacking
- SIMDCompressionAndIntersection: SIMD 命令を使用して整数のソート済みリストを圧縮および交差するための C++ ライブラリ https://github.com/lemire/SIMDCompressionAndIntersection
- FastPFOR C++ ライブラリ : 高速整数圧縮 https://github.com/lemire/FastPFor
- 高性能辞書コーディング https://github.com/lemire/dictionary
- LittleIntPacker: 整数の短い配列をできるだけ高速にパックおよびアンパックするための C ライブラリ https://github.com/lemire/LittleIntPacker
- StreamVByte: StreamVByte コーデックを使用した C での高速整数圧縮 https://github.com/lemire/streamvbyte
- MaskedVByte: VByte 圧縮された整数の高速デコーダー https://github.com/lemire/MaskedVByte
- CSharpFastPFOR: AC# 整数圧縮ライブラリ https://github.com/Genbox/CSharpFastPFOR
- JavaFastPFOR: Java 整数圧縮ライブラリ https://github.com/lemire/JavaFastPFOR
- エンコーディング: Go 用の整数圧縮ライブラリ https://github.com/zhenjl/encoding
- FrameOfReference は、フレームオブリファレンス (FOR) 圧縮専用の C++ ライブラリです: https://github.com/lemire/FrameOfReference
- libvbyte: varbyte 32 ビット/64 ビット整数圧縮の高速実装 https://github.com/cruppstahl/libvbyte
- TurboPFor は、多くの興味深い最適化を提供する C ライブラリです。チェックする価値は十分にあります! (GPLライセンス) https://github.com/powturbo/TurboPFor
- Oroch は、使用可能な API (MIT ライセンス) を提供する C++ ライブラリです https://github.com/ademakov/Oroch
他のプログラミング言語
- Julia のラッパーがあります。
- Rustポートがあります。
参考文献
- Daniel Lemire、Nathan Kurz、Christoph Rupp、Stream VByte: Faster Byte-Oriented Integer Compression、情報処理レター、情報処理レター 130、2018 年 2 月、ページ 1 ~ 6https://arxiv.org/abs/1709.08990
- Jianguo Wang、Chunbin Lin、Yannis Papakonstantinou、Steven Swanson、ビットマップ圧縮と反転リスト圧縮の実験的研究、SIGMOD 2017 http://db.ucsd.edu/wp-content/uploads/2017/03/sidm338-wangA。 pdf
- P. Damme、D. Habich、J. Hildebrandt、W. Lehner、軽量データ圧縮アルゴリズム: 実験的調査 (実験と分析)、EDBT 2017 http://openproceedings.org/2017/conf/edbt/paper-146。 pdf
- P. Damme、D. Habich、J. Hildebrandt、W. Lehner、軽量データ圧縮アルゴリズムの比較評価に関する洞察、EDBT 2017 http://openproceedings.org/2017/conf/edbt/paper-414.pdf
- Daniel Lemire、Leonid Boytsov、Nathan Kurz、SIMD 圧縮とソートされた整数の交差、ソフトウェアの実践と経験 46 (6) 2016。 http://arxiv.org/abs/1401.6399
- Daniel Lemire および Leonid Boytsov、「ベクトル化による 1 秒あたりの数十億の整数の解読」、Software Practice & Experience 45 (1)、2015 年。 http://arxiv.org/abs/1209.2137 http://onlinelibrary.wiley.com/doi/10.1002 /spe.2203/アブストラクト
- Jeff Plaisance、Nathan Kurz、Daniel Lemire、ベクトル化 VByte デコーディング、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、圧縮アルゴリズムを加速するための一般的な SIMD ベースのアプローチ、ACM Transactions on Information Systems 33 (3)、2015。 http ://arxiv.org/abs/1502.01916
- TD Wu、ゲノムのインデックス付けのためのビットパッキング技術: I. ハッシュ テーブル、分子生物学のアルゴリズム 11 (5)、2016。 http://almob.biomedcentral.com/articles/10.1186/s13015-016-0069-5