SIMDComp 库
一个简单的 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 等
它是做什么用的?
这是一个用于快速整数压缩的低级库。根据设计,它没有定义压缩格式。由(复杂的)用户创建压缩格式。
它的使用者:
要求
- 您的处理器应支持 SSE4.1(2008 年以来发布的大多数 Intel 和 AMD 处理器都支持 SSE4.1。)
- 如果您的处理器支持 SSE2(Pentium4 或更好),则可以构建代码的核心部分
- C99 兼容编译器(假定为 GCC)
- makefile 假定是类似 Linux 的发行版
对于不使用 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
- 快速 Bitpacking 算法:simdcomp 的 Rust 端口 https://github.com/quickwit-oss/bitpacking
- SIMDCompressionAndIntersection:一个 C++ 库,用于使用 SIMD 指令压缩和相交排序的整数列表 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 是一个 C++ 库,提供可用的 API(MIT 许可证)https://github.com/ademakov/Oroch
其他编程语言
参考
- Daniel Lemire、Nathan Kurz、Christoph Rupp,Stream VByte:更快的面向字节的整数压缩,信息处理快报,信息处理快报 130,2018 年 2 月,第 1-6 页https://arxiv.org/abs/1709.08990
- 王建国、林春斌、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,通过矢量化每秒解码数十亿个整数,软件实践与经验 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 解码,2015 年网络算法国际研讨会,2015 年。http://arxiv.org/abs/1503.07387
- 赵鑫、张旭东、Daniel Lemire、单东东、聂建云、颜鸿飞、温继荣,一种基于 SIMD 的通用加速压缩算法方法,ACM Transactions on Information Systems 33 (3),2015。 ://arxiv.org/abs/1502.01916
- TD Wu,用于索引基因组的位打包技术:I. 哈希表,分子生物学算法 11 (5),2016。http://almob.biomedcentral.com/articles/10.1186/s13015-016-0069-5