مكتبة SIMDComp
مكتبة C بسيطة لضغط قوائم الأعداد الصحيحة باستخدام التعبئة الثنائية وتعليمات SIMD. الافتراض هو إما أن لديك قائمة من الأعداد الصحيحة 32 بت حيث يكون معظمها صغيرًا، أو قائمة من الأعداد الصحيحة 32 بت حيث تكون الاختلافات بين الأعداد الصحيحة المتعاقبة صغيرة. لا يوجد برنامج قادر على ضغط مجموعة من الأرقام العشوائية ذات 32 بت بشكل موثوق.
يمكن لهذه المكتبة فك تشفير ما لا يقل عن 4 مليارات من الأعداد الصحيحة المضغوطة في الثانية على معظم معالجات سطح المكتب أو الكمبيوتر المحمول. أي أنه يمكنه فك ضغط البيانات بمعدل 15 جيجابايت/ثانية. يعد هذا أسرع بكثير من برامج الترميز العامة مثل gzip أو LZO أو Snappy أو LZ4.
على معالج Skylake Intel، يمكنه فك تشفير الأعداد الصحيحة بمعدل 0.3 دورة لكل عدد صحيح، والذي يمكن ترجمته بسهولة إلى أكثر من 8 مليارات من الأعداد الصحيحة التي تم فك تشفيرها في الثانية.
هذه المكتبة جزء من قائمة Awesome C لموارد لغة C.
المساهمين: دانييل لومير، ناثان كورز، كريستوف روب، أناتول بيلسكي، نيك وايت وآخرون
ما الغرض منه؟
هذه مكتبة منخفضة المستوى لضغط الأعداد الصحيحة بسرعة. حسب التصميم فإنه لا يحدد تنسيقًا مضغوطًا. الأمر متروك للمستخدم (المتطور) لإنشاء تنسيق مضغوط.
يتم استخدامه من قبل:
- upscaledb
- EventQL
- بحث مانتيكور
متطلبات
- يجب أن يدعم المعالج الخاص بك SSE4.1 (وهو مدعوم من قبل معظم معالجات Intel وAMD التي تم إصدارها منذ عام 2008.)
- من الممكن بناء الجزء الأساسي من الكود إذا كان معالجك يدعم SSE2 (Pentium4 أو أفضل)
- مترجم متوافق مع C99 (من المفترض أن تكون دول مجلس التعاون الخليجي)
- يفترض ملف makefile توزيعًا يشبه Linux
للحصول على إصدار C عادي لا يستخدم تعليمات SIMD، راجع 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 بت، تتم كتابة كلمات بحجم 128 بت فقط. وبالتالي فإن نسبة الضغط هي 32/ب.
- قوائم مرتبة من الأعداد الصحيحة.
استخدمنا الترميز التفاضلي: حيث نقوم بتخزين الفرق بين الأعداد الصحيحة المتعاقبة. لهذا الغرض، نحن بحاجة إلى قيمة أولية (تسمى الإزاحة).
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 السريعة: منفذ Rust لـ simdcomp 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: ضغط عدد صحيح سريع في لغة C باستخدام برنامج الترميز StreamVByte https://github.com/lemire/streamvbyte
- MaskedVByte: وحدة فك ترميز سريعة للأعداد الصحيحة المضغوطة باستخدام VByte https://github.com/lemire/MaskedVByte
- CSharpFastPFOR: مكتبة ضغط الأعداد الصحيحة AC# https://github.com/Genbox/CSharpFastPFOR
- JavaFastPFOR: مكتبة ضغط أعداد صحيحة جافا https://github.com/lemire/JavaFastPFOR
- الترميز: مكتبات ضغط الأعداد الصحيحة لـ Go https://github.com/zhenjl/encoding
- FrameOfReference هي مكتبة C++ مخصصة لضغط الإطار المرجعي (FOR): https://github.com/lemire/FrameOfReference
- libvbyte: تنفيذ سريع لضغط الأعداد الصحيحة varbyte 32 بت/64 بت https://github.com/cruppstal/libvbyte
- TurboPFor هي مكتبة لغة C تقدم الكثير من التحسينات المثيرة للاهتمام. تستحق التدقيق! (ترخيص GPL) https://github.com/powturbo/TurboPFor
- Oroch هي مكتبة C++ تقدم واجهة برمجة تطبيقات قابلة للاستخدام (ترخيص MIT) https://github.com/ademakov/Oroch
لغات البرمجة الأخرى
- هناك غلاف لجوليا.
- يوجد منفذ الصدأ.
مراجع
- دانيال ليمير، ناثان كورز، كريستوف روب، Stream VByte: ضغط صحيح موجه نحو البايت بشكل أسرع، رسائل معالجة المعلومات، رسائل معالجة المعلومات 130، فبراير 2018، الصفحات 1-6https://arxiv.org/abs/1709.08990
- جيانغو وانغ، تشونبين لين، يانيس باباكونستانتينو، ستيفن سوانسون، دراسة تجريبية لضغط الصور النقطية مقابل ضغط القائمة المقلوبة، SIGMOD 2017 http://db.ucsd.edu/wp-content/uploads/2017/03/sidm338-wangA. قوات الدفاع الشعبي
- P. Damme, D. Habich, J. Hildebrandt, W. Lehner، خوارزميات ضغط البيانات خفيفة الوزن: مسح تجريبي (تجارب وتحليلات)، EDBT 2017 http://openproceedings.org/2017/conf/edbt/paper-146. قوات الدفاع الشعبي
- P. Damme, D. Habich, J. Hildebrandt, W. Lehner، رؤى في التقييم المقارن لخوارزميات ضغط البيانات خفيفة الوزن، EDBT 2017 http://openproceedings.org/2017/conf/edbt/paper-414.pdf
- دانيال لومير، ليونيد بويتسوف، ناثان كورز، ضغط SIMD وتقاطع الأعداد الصحيحة المصنفة، ممارسة البرمجيات والخبرة 46 (6) 2016. http://arxiv.org/abs/1401.6399
- دانيال ليمير وليونيد بويتسوف، فك تشفير مليارات الأعداد الصحيحة في الثانية من خلال التوجيه، ممارسة البرمجيات والخبرة 45 (1)، 2015. http://arxiv.org/abs/1209.2137 http://onlinelibrary.wiley.com/doi/10.1002 /spe.2203/abstract
- جيف بليزانس، ناثان كورز، دانييل لومير، فك تشفير VByte المتجه، الندوة الدولية حول خوارزميات الويب 2015، 2015. http://arxiv.org/abs/1503.07387
- واين شين تشاو، شودونج تشانغ، دانييل ليمير، دونغدونغ شان، جيان يون ني، هونغفي يان، جي رونغ ون، نهج عام قائم على SIMD لتسريع خوارزميات الضغط، معاملات ACM على أنظمة المعلومات 33 (3)، 2015. http //arxiv.org/abs/1502.01916
- تي دي وو، تقنيات Bitpacking لفهرسة الجينومات: I. جداول التجزئة، خوارزميات البيولوجيا الجزيئية 11 (5)، 2016. http://almob.biomedcentral.com/articles/10.1186/s13015-016-0069-5