More Related Content
Similar to An Experimental Study of Bitmap Compression vs. Inverted List Compression
Similar to An Experimental Study of Bitmap Compression vs. Inverted List Compression(20)
More from Takeshi Yamamuro
More from Takeshi Yamamuro(20)
An Experimental Study of Bitmap Compression vs. Inverted List Compression
- 1. 1
担当: Takeshi Yamamuro
SIGMOD’17
Session
20:
Op4miza4on
and
performance
- 6. 6
共通する解いている問題
• 昇順に並び替えられた整数を少ないbitで表現しつ
つ、高速な問い合わせ(e.g.,
A∩B)を実現
ビットマップ圧縮
-‐
ビットが立っている位置は昇順の整数:
011001
-‐>
1,2,5
-‐
適用例:
PostgreSQL/OracleなどのRDBMSやApache
Spark/Hiveなど
整数圧縮
-‐
転置インデックスのドキュメントID、昇順に並び替えて保存
-‐ 主な適用例:
Apache
Lucene/Solr、Elas4csearchなど(近年では
DBMS内部の要素技術としてもよく利用される)
A
=
1,
4,
8,
10,
19,
…
B
=
4,
14,
18,
19,
22,
…
A
∩ B
=
4,
19,
…
特定の問い合わせを高速に処理で
きる効率的なコンピュータ上の表現
(符号化)方法を模索
- 7. 7
Apache Sparkにおける適用例
• Spark
SQLでcacheしたデータはカラム構造(型毎の配列)と
してメモリ上に配置され、整数配列はVBで表現
• SparkのSchedulerが各Task(実行最小単位)の出力サイズ
を追跡、出力が無いTaskをRoaring
Bitmapsで管理
• h`p://roaringbitmap.org
• Lemire先生が書いた
RoaringのOSS実装
・・・
- 8. 8
圧縮アルゴリズム紹介(抜粋)
• ビットマップ圧縮
• RLEベースの手法:
WAH,
EWAH,
PLWAH,
CONCISE,
VALWAH,
SBH,
BBC
• Hybridな手法:
Roaring
• 整数圧縮
•
VB,
PforDelta,
[New|Opt|SIMD]PforDelta,
Simple16,
GroupVB,
Simple8b,
PEF,
SIMDBP128
- 9. 9
ビットマップ圧縮: WAH
• RLEベースの古典的なビットマップ圧縮手法
• ビット列を31bitずつのgroupsに分割
• グループを2種類に分類:
fill
groups
or
literal
groups
fill
groups:
ビットが全て同じグループ(0-‐fill
groups
or
1-‐fill
groups)
literal
groups:
上記以外のグループ
• fill
groupsのみをRLEで圧縮、分割したgroupsの先頭に1bitの
groups判定フラグ1bitを付与(1の場合fill
groups)
• fill
groupsの場合、2bit目でfill
groupsの種類(0
or
1)を表し、残りの
30bitでrunの長さを表現
具体例) 入力ビット列:
1020
13
0111
125
(160bit)
G1(1020
13
07)
G2(031)
G3(031)
G4(031)
G5(011120)
G6(02615)
010201307
10027011
0011120
002615
- 10. 10
ビットマップ圧縮: SBH
• WAHの改良版の手法
• ビット列を7bitずつのgroupsに分割
• 連続するfill-‐groupsの数k(k
<=
4093)で表現方法を変える
63
>=
k:
1byteでfill-‐groupsを表現
63
<
k
<=
4093:
2byteでfill-‐groupsを表現
• 具体例) 入力ビット列:
1020130501160(532bit)
G1(106)
G2(07)
G3(07)
G4(1304)G5(07)...G76(07)G78(160)
0106
10000010
(k
=
2)
01304
01304
1031031061
(k
=
72)
- 11. 11
ビットマップ圧縮: Roaring
• 2016年に提案された最新のビットマップ圧縮手法
• RLEベースではなく、ビット密度(Cardinality)に応じて表現
方法を変えるハイブリッドな手法
• ビット列を上位16bitが共通しているbucketに分割
• 各bucket内のビット数kで表現を変更
4096
>
k,
dense:
65536-‐bit
uncompressed
bitmap
4096
<=
k
sparse:
sorted
16bit
ints.
• 実装の詳細は以下のスライドが理解しやすい
• h`ps://spark-‐summit.org/east-‐2017/speakers/daniel-‐lemire/
- 12. 12
整数圧縮: VB
• 小さい値を少ないbyte数で表現
• 1byteの先頭1bitを境界を表すヘッダとして扱い7bitで値を表現
• 先頭bitを見て条件分岐をするためCPUペナルティが大きい
• Group
VB
• 32bitの4つの値をまとめて圧縮
• 復元処理の際の条件分岐をshii/maskを使い削減
引用:
h`ps://www.slideshare.net/parallellabs/building-‐soiware-‐
systems-‐at-‐google-‐and-‐lessons-‐learned/44-‐
ByteAligned_Variablelength_Encodings_Varint_encoding
- 13. 13
整数圧縮: PforDelta
Super-‐Scalar
RAM-‐CPU
Cache
Compression,
ICDE’06から引用
復元処理のコード例
• MonetDB/X100プロジェクト(CWI)の研究の一環で提案され
たCPU最適化された整数圧縮手法
• 128個のd-‐gapsを1つのブロックとして、ブロック内の大半(e.g.,
90%
以上)を表現可能な最小bit数kを決定(右図ではk=3)
• k-‐bit以下の値はk-‐bitの値としてbit-‐packing(右図のcode
selec4on)
• k-‐bitを超えた値は例外として圧縮せずにexcep4on
sec4onに格納
1:
まずk-‐bit以下の値は条件分岐なしに一括で復元
2:
例外値を最後にパッチワーク
- 14. 14
整数圧縮: PforDelta
Super-‐Scalar
RAM-‐CPU
Cache
Compression,
ICDE’06から引用
復元処理のコード例
• 2008〜2015年に様々な亜種の手法が提案
• 例外値も圧縮できるようにしたものがNewPforDelta、kの値を最適
化したものがOptPforDelta、復元処理をSIMDを使ってデータ並列
処理化したものがSIMDPforDelta
1:
まずk-‐bit以下の値は条件分岐なしに一括で復元
2:
例外値を最後にパッチワーク
- 15. 15
整数圧縮: SIMDBP128
• 復元処理をSIMD命令を使い最適化した手法
• 入力列を128個ずつの整数ブロックに分割、16個のブロッ
ク毎に16byteのメタデータを付与
• 各ブロックをk-‐bit(表現可能な最小のbit数)でm個ずつbit-‐packing
• kとmの値をメタデータ記録
• 復元処理はメタデータから必要な関数(SIMDunpackk_m)
を判断して呼び出す
5bitで表現された値8個をSIMD命令で復元するコード([25]から引用)
- 16. 16
補足)制御依存からデータ依存への変換
• アルゴリズムから条件分岐(if-‐then-‐else)を排除
• 分岐予測が外れると~20clk程度のペナルティ
• RoaringやSIMDPforDelta/SIMDBP128などの近代的な手法は考慮
• 参考資料:
“条件分岐とcmovとmaxps”
• h`ps://www.slideshare.net/herumi/cmovmaxps
Super-‐Scalar
RAM-‐CPU
Cache
Compression,
ICDE’06から引用
• 条件分岐はIPCの敵
• Xeon/Opteronでは分岐予測が最
も外れる条件でIPC値が低下
- 18. 18
補足)制御依存からデータ依存への変換
• 簡単な例)2分探索
• 条件分岐を排除するためにデータ配列を再配置、比較
結果から移動オフセットを計算して探索
探索値との比較結果
移動オフセット
探索値 <
データ値
2log(k+1)-‐1
探索値 >
データ値
1
4
2
1
3
6
5
7
1回目の探索範囲 k
=
7
2回目の探索範囲 k
=
3
再配置したデータ配列:
1回目の移動オフセット
=
2log(7+1)-‐1
=
4
2回目の移動オフセット
=
1
- 20. 20
実験条件
• CPU:
Intel
i7-‐4770
w/AVX2を利用
• 全てメモリ上で性能を比較
• 全ての手法をC++で実装して、gcc-‐4.4.7の-‐O3でコンパイル
• 比較する4つの指標(圧縮時間に関する言及はなし)
• Space
overhead
• Decompression
4me
• Intersec4on
4me
• Union
4me
• 使用するデータセット
• 人工的に生成したデータ:
Uniform,
Zipf,
Markov
process
• 実データ:
DBMS(Star
Schema
Benchmark、TPC-‐H)、
Web(clueweb12)、グラフ(twi`er)、KDDCup99、温度
(Berkeleyearch)、信号(Higgs)、ゲノム(Kegg)
- 21. 21
実験結果: 圧縮率と復元速度
• 総合的にビットマップ圧縮に比べて整数圧縮の性能が良い、
特にSIMDPforDeltaとSIMDBP128が良い
• Sparseな場合、RLEベースのビットマップ圧縮では0-‐fill
wordsを表現
するために必ず32bit必要だが、整数圧縮で用いるd-‐gapsはより少
ないbitで表現可能
• Denseな場合、整数圧縮はd-‐gapsの外れ値に弱いため圧縮率が悪
くなるが、復元性能はビットマップ圧縮より良い
Sparse
Dense
- 22. 22
実験結果: 圧縮率と復元速度
• ビットマップ圧縮の中では断然Roaringの性能が良い
• 意外だが結果からRLEはビットマップの圧縮には向いていないとい
う結論、RLEに頼らないRoaringが性能的に優位
• ビット密度に応じて表現方法(16bit
ints
or
bitmap)を切り替えるハ
イブリッドな手法が性能に寄与
Sparse
Dense
- 23. 23
実験結果: 圧縮率と復元速度
• Zipf分布ではシンプルな手法であるVBの復元速度がCPU最
適化されたPforDeltaより良くなるケースがある
• 先行研究[42]ではPforDeltaはVBに対して復元性能が劣るケース
は報告されていなかった
• byte-‐wiseなVBはbit-‐wiseなPForDeltaには圧縮率では劣るが、byte
単位のアクセス効率の良さが顕在化した?
Sparse
Dense
- 24. 24
実験結果: IntersecGonの速度
• Intersec4onは安定してRoaringの性能が良い
Sparse
Dense
• 各bucket内の表現(16bit
ints
or
bitmap)はIntersectを
効率的に行うための設計
• 不必要なbucketをskipして、
必要なbucket間で処理を行
うため効率的
•
整数圧縮ではSIMDBP128
とPEFの性能が良い
• PEFはd-‐gapsを使わないため
任意部分を復元でき、効率
的にintersec4onが可能
• PEFは復元性能は低いため、
偏ったデータ(zipf)の場合性
能が悪化
- 25. 25
実験結果: Unionの速度
•
整数圧縮がビットマップ圧縮より性能が良い
Sparse
Dense
• 復元するデータ量が多い為
基本的には復元性能の高
い手法(SIMDPforDeltaと
SIMDBP128)が有利
• ビットマップ圧縮では圧縮率
と復元速度を含めてRoaring
の性能が最も良い
- 26. 26
実験結果: 実データ(SSB)
• 選択率の異なる4つのクエリ(Q1.1,
Q2.1,
Q3.4,
Q4.1)を用い
て圧縮率とintersec4onの速度を比較
• Q1.1,
Q2.1,
Q4.1はデータがdenseであるためRoaringの
intersec4on性能が良い、Q3.4はsparseよりのデータであるた
め整数圧縮もcompe44ve
• 圧縮率も考慮すると総合的にRoaringを選択するべき
- 27. 27
実験結果: 実データ(TPC-‐H)
• SSBと同様に選択率の異なるクエリ(Q6,
Q12)を用いて圧縮
率とintersec4onの速度を比較
• denseなデータであるQ6ではRoaringが性能が最も良いが、
sparse傾向にあるQ12では圧縮率のみ悪化
- 28. 28
実験結果: 実データ(グラフ)
• twi`erの隣接リストのデータから任意の頂点を3つ選択(L1,
L2,
L3)して圧縮率とintersec4onの速度を比較
• Q1:
|L1|=960,
|L2|=50913,
|L3|=507777
• Q2:
|L1|=507777,
|L2|=526292,
|L3|=779957
• 総合的にビットマップ圧縮に比べて整数圧縮の性能が良い
• データ密度の言及はないが、これまでの結果からSparseな傾向の
データだと推測される
- 29. 29
所感
引用:
NUMA
obliviousness
through
memory
mapping,
DaMoN'15
• SIMDBP128は提案論文[25]によると2,000
million
int./sを超
える復元性能を達成するらしいが、単スレッドで8GB/s近く
消費する計算になる
• 近年のCPU-‐メモリ間の最大帯域は
40-‐60GB/s程度なので8並列以下で
上限を超えてしまう
実際は入力の並列数を考慮して、
帯域の上限を超えない範囲でク
エリ性能を最大化する手法を選
ぶ必要がありそう
- 30. 30
補足)併せて読みたい論文
• 同著者のVLDB’17論文
• 圧縮率とクエリ性能の両立す
る整数圧縮MILCを提案
• 性能の観点でd-‐gapsではなく
offsetを使用
• 圧縮率の観点でブロック長を固
定ではなく、長さを最適化
(VSEncoding-‐like)
• キャッシュ考慮&SIMD並列