SCAN + JOIN + GROUP BY Combined Kernel (1/3)
Aggregation
GROUP BY
JOIN
SCAN
SELECT cat, count(*), avg(x)
FROM t0 JOIN t1 ON t0.id = t1.id
WHERE y like ‘%abc%’
GROUP BY cat;
count(*), avg(x)
GROUP BY cat
t0 JOIN t1
ON t0.id = t1.id
WHERE y like ‘%abc%’
実行結果
HBStudy#80 - GPUとSSDがPostgreSQLを加速する23
GpuScan
GpuJoin
Agg
+
GpuPreAgg
v2.0
PostgreSQLは集計クエリを何ステップかに分解して実行する。
データ受け渡し
データ受け渡し
SCAN + JOIN + GROUP BY Combined Kernel (2/3)
集約演算まで一気にGPU側で行ってしまう事で、
ロードすべきデータ量を極端に削減する事ができる。
GpuScan
kernel
GpuJoin
kernel
GpuPreAgg
kernel
Agg
(PostgreSQL)
GPU
CPU
Storage
実行
結果
GpuScan + GpuJoin + GpuPreAgg Combined Kernel
data size
= large
data size
= small
HBStudy#80 - GPUとSSDがPostgreSQLを加速する24
v2.0
Data
Blocks
SCAN + JOIN + GROUP BY Combined Kernel (3/3)
HBStudy#80 - GPUとSSDがPostgreSQLを加速する25
10GBのデータをスキャンして、
最終的にCPU側へ書き戻されたのは 1.2kB のみ。
v2.0
〈補足〉ハードウェア構成に関する考慮事項
HBStudy#80 - GPUとSSDがPostgreSQLを加速する30
▌マルチGPU環境への対応
SQLの実行開始時に、スキャンすべきテーブルを保持するSSDに至近のGPUを使う。
PostgreSQL v10は複数の異なるテーブルを並列スキャンできないため、
マルチGPU環境下でのSSD-to-GPUダイレクトSQL実行は必ずしも効率的ではない。
PostgreSQL v11の “Parallel Append” 機能を待って対応予定。
① PCIeスイッチを介して
SSDとGPUが接続の場合
OK
② CPUがPCIeバスを管理し、
SSDにGPU直接接続の場合
Workable
③ SSDとGPUが互いに異なる
CPUに接続の場合
Not Supported
CPU CPU
PLX
SSD GPU
PCIeスイッチ
CPU CPU
SSD GPU
CPU CPU
SSD GPU
QPI
SSDとGPUのペアは、同一CPUまたはPLXの配下に接続されている必要がある
検証事例)PL/CUDA関数の呼び出し例
HBStudy#80 - GPUとSSDがPostgreSQLを加速する51
SELECT row_number() OVER (),
float4_as_int4(R.key_id) key_id,
R.score
FROM matrix_unnest(
(SELECT my_plcuda_function(A.matrix,
B.matrix)
FROM (SELECT cbind(array_matrix(id),
array_matrix(x, y, z)) matrix
FROM normal_table
WHERE tag LIKE ‘%abc%’) A,
(SELECT matrix
FROM matrix_table) B
)
) AS R(key_id real, score real)
ORDER BY score DESC
LIMIT 1000;
2つのMatrix-like Arrayを
引数に持つ
PL/CUDA関数の呼出し
Matrix-like Arrayの生成、
または構築済みのものをロード
Matrix-like Arrayを
N個のレコードに再展開
SQLによる後処理
(JOIN, Window関数)