OS환경 : Oracle Linux 6.8 (64bit)
DB 환경 : Oracle Database 11.2.0.4
방법 : linux7.6에 PostgreSQL 10 + PG-Strom 2.2 GPU 사용 테스트
이어지는글 : linux7.6에 PostgreSQL 10 + PG-Strom 2.2 구성하기(성공)
GPU 사용 테스트
GPU를 사용하는지 테스트 해보기 위해 샘플테이블 3개 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | # su - postgres $ psql psql> drop table t0; drop table t1; drop table t2; CREATE TABLE t0 AS SELECT gs as cat, gs as ax, gs as aid, gs as bid, 'imsidata' || gs AS test_string, md5(random()::text) AS random_string FROM generate_series(1, 100000) AS gs; CREATE TABLE t1 AS SELECT gs as cat, gs as ax, gs as aid, gs as bid, 'imsidata' || gs AS test_string, md5(random()::text) AS random_string FROM generate_series(1, 100000) AS gs; CREATE TABLE t2 AS SELECT gs as cat, gs as ax, gs as aid, gs as bid, 'imsidata' || gs AS test_string, md5(random()::text) AS random_string FROM generate_series(1, 100000) AS gs; |
EXPLAIN 명령을 사용해 실행계획 확인
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | psql> # EXPLAIN SELECT cat,count(*),avg(ax) FROM t0 NATURAL JOIN t1 NATURAL JOIN t2 GROUP BY cat; QUERY PLAN -------------------------------------------------------------------------------- GroupAggregate (cost=989186.82..989190.94 rows=27 width=20) Group Key: t0.cat -> Sort (cost=989186.82..989187.29 rows=189 width=44) Sort Key: t0.cat -> Custom Scan (GpuPreAgg) (cost=989175.89..989179.67 rows=189 width=44) Reduction: Local GPU Projection: cat, pgstrom.nrows(), pgstrom.nrows((ax IS NOT NULL)), pgstrom.psum(ax) Combined GpuJoin: enabled -> Custom Scan (GpuJoin) on t0 (cost=14744.40..875804.46 rows=99996736 width=12) GPU Projection: t0.cat, t1.ax Outer Scan: t0 (cost=0.00..1833360.36 rows=99996736 width=12) Depth 1: GpuHashJoin (nrows 99996736...99996736) HashKeys: t0.aid JoinQuals: (t0.aid = t1.aid) KDS-Hash (size: 10.39MB) Depth 2: GpuHashJoin (nrows 99996736...99996736) HashKeys: t0.bid JoinQuals: (t0.bid = t2.bid) KDS-Hash (size: 10.78MB) -> Seq Scan on t1 (cost=0.00..1972.85 rows=103785 width=12) -> Seq Scan on t2 (cost=0.00..1935.00 rows=100000 width=4) (21 rows) |
실행 계획 속에 익숙하지 않은 구문이 포함되어있음(GPU Projection 등)
CustomScan 매커니즘을 이용해서 GpuJoin 및 GpuPreAgg이 구현되어 있음
여기서 GpuJoin은 t0과 t1 및 t2와 JOIN 작업을 수행하고 그 결과를 GpuPreAgg가 받은 뒤
GPU에서 cat 컬럼으로 GROUP BY를 실행함
PostgreSQL가 쿼리 실행 계획을 구축하는 과정에서 PG-Strom는 최적화에 개입하고
SCAN, JOIN, GROUP BY의 각 워크로드를 GPU에서 실행 가능한 경우 그 비용(Cost)을 산출하여
PostgreSQL의 최적화 실행 계획 후보를 제시함
추정 된 비용(Cost) 값이 CPU에서 실행되는 실행 계획보다 작은 값인 경우, GPU를 이용한 대체 실행 계획이 선택됨
GPU 실행을 위해서는 사용중인 연산자, 기능 및 데이터 유형이 PG-Strom에서 지원되어야함
int 나 float 같은 수치 형, date 또는 timestamp 같은 시각 형, text와 같은 문자열이 지원되고 있으며,
사칙 연산과 대소 비교 등 다양한 내장 연산자가 지원됨 전체 목록은 레퍼런스를 참조해야함
아래 내용부터는 데이터가 1억건 이상이라 참고용으로만 보기 바람
http://heterodb.github.io/pg-strom/operations/ 내용을 그대로 가져와서
한글 문장이 어색한 부분만 수정한 내용임
CPU + GPU 하이브리드 병렬
PG-Strom은 PostgreSQL의 CPU 병렬 실행도 지원함
CPU 병렬 실행 모드에서 Gather 노드는 여러 백그라운드 워커 프로세스를 시작한 다음
개별 백그라운드 워커에 의한 "부분"실행 결과를 수집함
GpuJoin 또는 GpuPreAgg와 같은 PG-Strom에서 제공하는 CustomScan 실행 계획은 백그라운드에서의 실행을 지원함
GPU를 사용하여 부분 작업을 개별적으로 처리함
CPU 코어는 일반적으로 GPU에서 SQL 워크로드를 실행하는 것보다 GPU에 데이터를 제공하기 위해
버퍼를 설정하는 데 훨씬 더 많은 시간이 필요하므로 CPU와 GPU 병렬의 하이브리드 사용은 더 높은 성능을 기대할 수 있음 반면에 각 프로세스는 GPU와 통신하는 데 필요한 CUDA 컨텍스트를 생성하고 특정 양의 GPU 리소스를 소비하므로 CPU 측의 병렬 처리가 항상 좋은 것은 아님
아래의 쿼리 실행 계획을 보면 수집 아래의 실행 계획 트리는 백그라운드 작업자 프로세스에서 실행 가능합니다. t04 개의 백그라운드 작업자 프로세스와 코디네이터 프로세스를 사용하여 1 억 개의 행이있는 테이블을 스캔 합니다. 즉, GpuJoin 및 GpuPreAgg에 의해 프로세스 당 2 천만 개의 행이 처리 된 후 결과가 Gather 노드에서 병합됩니다.
아래 실행 계획을 보면 Gather 다음 실행 계획은 백그라운드에서 실행됨
4 개의 백그라운드 작업자 프로세스와 코디네이터 프로세스를 사용하여 1 억 개의 행이있는 t0 테이블을 스캔함
스캔하기 위해 프로세스 당 2000만 행을 GpuJoin 및 GpuPreAgg 처리하고 그 결과를 Gather 노드에 결합함
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | psql> EXPLAIN SELECT cat,count(*),avg(ax) FROM t0 NATURAL JOIN t1 GROUP by cat; QUERY PLAN -------------------------------------------------------------------------------- GroupAggregate (cost=955705.47..955720.93 rows=27 width=20) Group Key: t0.cat -> Sort (cost=955705.47..955707.36 rows=756 width=44) Sort Key: t0.cat -> Gather (cost=955589.95..955669.33 rows=756 width=44) Workers Planned: 4 -> Parallel Custom Scan (GpuPreAgg) (cost=954589.95..954593.73 rows=189 width=44) Reduction: Local GPU Projection: cat, pgstrom.nrows(), pgstrom.nrows((ax IS NOT NULL)), pgstrom.psum(ax) Combined GpuJoin: enabled -> Parallel Custom Scan (GpuJoin) on t0 (cost=27682.82..841218.52 rows=99996736 width=12) GPU Projection: t0.cat, t1.ax Outer Scan: t0 (cost=0.00..1083384.84 rows=24999184 width=8) Depth 1: GpuHashJoin (nrows 24999184...99996736) HashKeys: t0.aid JoinQuals: (t0.aid = t1.aid) KDS-Hash (size: 10.39MB) -> Seq Scan on t1 (cost=0.00..1972.85 rows=103785 width=12) (18 rows) |
풀업 기본 계획
PG-Strom은 GPU에서 SCAN, JOIN 및 GROUP BY 워크로드를 실행할 수 있지만
이러한 사용자 정의 실행 계획이 PostgreSQL의 표준 작업을 단순히 대체하는 경우 최상의 성능으로 작동하지 않음
문제가있는 시나리오의 예는 SCAN이 결과 데이터 세트를 호스트 버퍼에 다시 쓴 후
동일한 데이터를 GPU로 다시 보내 JOIN을 실행하는 것임
다시 한 번, JOIN 결과가 다시 기록되고 GPU로 전송되어 GROUP BY를 실행함
이렇게 CPU와 GPU간에 데이터 핑퐁이 발생함
이러한 비효율적 인 작업을 피하기 위해 PG-Strom에는
단일 GPU 커널 호출에서 많은 작업을 실행하기 위해 하위 계획을 끌어내는 특수 모드가 있음
작업 블로우를 조합하면 하위 계획이 풀업 될수 있음
SCAN + JOIN
SCAN + GROUP BY
SCAN + JOIN + GROUP BY
http://heterodb.github.io/pg-strom/operations/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | psql> EXPLAIN SELECT cat,count(*),avg(ax) FROM t0 NATURAL JOIN t1 WHERE aid < bid GROUP BY cat; QUERY PLAN -------------------------------------------------------------------------------- GroupAggregate (cost=1239991.03..1239995.15 rows=27 width=20) Group Key: t0.cat -> Sort (cost=1239991.03..1239991.50 rows=189 width=44) Sort Key: t0.cat -> Custom Scan (GpuPreAgg) (cost=1239980.10..1239983.88 rows=189 width=44) Reduction: Local GPU Projection: cat, pgstrom.nrows(), pgstrom.nrows((ax IS NOT NULL)), pgstrom.psum(ax) -> Custom Scan (GpuJoin) (cost=50776.43..1199522.96 rows=33332245 width=12) GPU Projection: t0.cat, t1.ax Depth 1: GpuHashJoin (nrows 33332245...33332245) HashKeys: t0.aid JoinQuals: (t0.aid = t1.aid) KDS-Hash (size: 10.39MB) -> Custom Scan (GpuScan) on t0 (cost=12634.49..1187710.85 rows=33332245 width=8) GPU Projection: cat, aid GPU Filter: (aid < bid) -> Seq Scan on t1 (cost=0.00..1972.85 rows=103785 width=12) (18 rows) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | psql> EXPLAIN ANALYZE SELECT cat,count(*),avg(ax) FROM t0 NATURAL JOIN t1 WHERE aid < bid GROUP BY cat; QUERY PLAN -------------------------------------------------------------------------------- GroupAggregate (cost=903669.50..903673.62 rows=27 width=20) (actual time=7761.630..7761.644 rows=27 loops=1) Group Key: t0.cat -> Sort (cost=903669.50..903669.97 rows=189 width=44) (actual time=7761.621..7761.626 rows=27 loops=1) Sort Key: t0.cat Sort Method: quicksort Memory: 28kB -> Custom Scan (GpuPreAgg) (cost=903658.57..903662.35 rows=189 width=44) (actual time=7761.531..7761.540 rows=27 loops=1) Reduction: Local GPU Projection: cat, pgstrom.nrows(), pgstrom.nrows((ax IS NOT NULL)), pgstrom.psum(ax) Combined GpuJoin: enabled -> Custom Scan (GpuJoin) on t0 (cost=12483.41..863201.43 rows=33332245 width=12) (never executed) GPU Projection: t0.cat, t1.ax Outer Scan: t0 (cost=12634.49..1187710.85 rows=33332245 width=8) (actual time=59.623..5557.052 rows=100000000 loops=1) Outer Scan Filter: (aid < bid) Rows Removed by Outer Scan Filter: 50002874 Depth 1: GpuHashJoin (plan nrows: 33332245...33332245, actual nrows: 49997126...49997126) HashKeys: t0.aid JoinQuals: (t0.aid = t1.aid) KDS-Hash (size plan: 10.39MB, exec: 64.00MB) -> Seq Scan on t1 (cost=0.00..1972.85 rows=103785 width=12) (actual time=0.013..15.303 rows=100000 loops=1) Planning time: 0.506 ms Execution time: 8495.391 ms (21 rows) |
참조 : http://heterodb.github.io/pg-strom/operations/
https://positivemh.tistory.com/469
http://bysql.net/w201101B/13925
'PostgreSQL > Admin' 카테고리의 다른 글
PostgreSQL 10 유저 Password_encryption 변경 (0) | 2020.02.24 |
---|---|
PostgreSQL 10, oracle fdw extension 으로 오라클 DB와 연결(dblink) 정리 (0) | 2019.11.27 |
oracle_utils.c:22:17: fatal error: oci.h: No such file or directory (0) | 2019.11.27 |
PostgreSQL 10 유저 superuser 권한, 롤 부여 (0) | 2019.11.04 |
PostgreSQL 10 pg_dump 사용 테스트(40GB) (0) | 2019.10.30 |