SIMDComp 라이브러리
바이너리 패킹 및 SIMD 명령어를 사용하여 정수 목록을 압축하기 위한 간단한 C 라이브러리입니다. 대부분이 작은 32비트 정수 목록이 있거나 연속된 정수 간의 차이가 작은 32비트 정수 목록이 있다고 가정합니다. 32비트 난수 배열을 안정적으로 압축할 수 있는 소프트웨어는 없습니다.
이 라이브러리는 대부분의 데스크탑 또는 노트북 프로세서에서 초당 최소 40억 개의 압축 정수를 디코딩할 수 있습니다. 즉, 15GB/s의 속도로 데이터의 압축을 풀 수 있습니다. 이는 gzip, LZO, Snappy 또는 LZ4와 같은 일반 코덱보다 훨씬 빠릅니다.
Skylake Intel 프로세서에서는 정수당 0.3사이클의 속도로 정수를 디코딩할 수 있으며, 이는 초당 80억 개가 넘는 디코딩된 정수로 쉽게 변환될 수 있습니다.
이 라이브러리는 C 리소스의 Awesome C 목록의 일부입니다.
기여자: Daniel Lemire, Nathan Kurz, Christoph Rupp, Anatol Belski, Nick White 외
그것은 무엇을 위한 것입니까?
이는 빠른 정수 압축을 위한 저수준 라이브러리입니다. 설계상 압축 형식을 정의하지 않습니다. 압축 형식을 만드는 것은 (정교한) 사용자의 몫입니다.
다음에서 사용됩니다.
요구사항
- 프로세서는 SSE4.1을 지원해야 합니다(2008년 이후 출시된 대부분의 Intel 및 AMD 프로세서에서 지원됩니다.)
- 프로세서가 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
- 빠른 비트패킹 알고리즘: 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 32bit/64bit 정수 압축을 위한 빠른 구현 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: 더 빠른 바이트 중심 정수 압축, 정보 처리 편지, 정보 처리 편지 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, 벡터화를 통해 초당 수십억 개의 정수 디코딩, Software Practice & Experience 45 (1), 2015. http://arxiv.org/abs/1209.2137 http://onlinelibrary.wiley.com/doi/10.1002 /spe.2203/abstract
- Jeff Plaisance, Nathan Kurz, Daniel Lemire, 벡터화된 VByte 디코딩, 웹 알고리즘에 관한 국제 심포지엄 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 트랜잭션 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