スキャン速度10GB/sへの挑戦~その③~

ちょっと前(2017年10月)に以下のような記事を書いた。
kaigai.hatenablog.com

この時点では、SeqRead 2.2GB/s の Intel SSD 750(400GB) を3枚束ねて、理論帯域6.6GB/sに対してクエリ処理のスループット6.2GB/s程度までは能力を引き出す事ができていた。
データを受け取るGPUの側は使用率30-40%程度で動いているので、SSDからのデータ供給を増加させてやれば、まだまだ処理速度を上げられるハズである。

というワケで新しいSSDを調達してみた。Intel DC P4600である。

このデバイスは PCIe x4接続のNVMe-SSDとしては最速に近い SeqRead 3.2GB/s の能力を持っており、単純に3枚束ねれば 9.6GB/s 程度の読出しスループットが期待できる。
が、そうは問屋が下ろさなかった。

手元の評価機は Xeon E5-2650v4 (Broadwell) を搭載しているのだが、どうやら P2P DMA の転送レートが 7.2GB/s 近辺で頭打ちになってしまうらしく、ちょっと頭を抱えていた。*1

HPC用の特別なH/Wを除けば、一般的なx86サーバではCPUがPCIeのRoot Complexも兼ねているので、PCIeバス上を流れるパケットのルーティングに関わる性能問題であれば、どうもCPUが被疑なのでは・・・という気になってしまう。

そういった折、ちょうどTesla V100を入手できる事になり、ならばよい機会とGPUを搭載するサーバを一新する事にした。つまり、今回の記事は新しいサーバの自慢である。

SuperServer 1019GP-TT

調達したモデルはSuperMicro社の 1019GP-TT で、その他の搭載機器は以下のとおりである。

Chasis SuperMicro 1019GP-TT
CPU Intel Xeon Gold 6126T (2.6GHz, 12C)
RAM 192GB (DDR4-2666; 32GBx6)
GPU NVIDIA Tesla V100 (5120C, 16GB)
SSD Intel DC P4600 (2.0TB) x3
HDD 2.0TB(SATA; 7.2krpm)x6


こちらが届いたばかりの筐体。
このモデルは本来、左右中央にそれぞれPCIe x16スロットを持っており、フルハイト・フルレングスのGPUを最大2枚搭載する事ができる。中央のスロットはLow Profile用なので、おそらくInfinibandか100Gb EthernetのHBAでも搭載するという構成なのだろう。
これを、ライザカード(RSC-R1UG-2E8G-UP)を使う事で写真の向かって左側スロットをPCIe x16からPCIe x8+x8に分配している。このように組み替える事で、GPUに加えてSSDを3枚搭載するだけのスペースを確保する事ができる。
なお、向かって右側スロットをPCIe x8+x8構成にする事もできるのだが、この場合、必然的にGPUが左側に押し出され、電源ピン位置がデバイス冷却用のファンに近くなって配線がタイトになってしまう。ので、作業スペースを考えると左側の2slot化がベスト。


こちらが各デバイスを搭載した状態。

Star Schema Benchmarkによる計測と困惑

で、OS、CUDA、PostgreSQLとPG-Stromをインストールし、いつものStar Schema Benchmarkで性能測定を行ってみる。

実行中のI/O負荷を iostat で眺めてみると以下のような数字(約 8.5GB/s)が出ていた。
これは Raw-I/O での計測値とほぼ同じで、ベンチマークの中核であるlineorderテーブルのスキャンとJOIN/GROUP BYの実行に関しては、ほぼハードウェアの限界に近い所まで引き出せているのだろう。

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           1.34    0.00    5.40    0.00    0.00   93.25

Device:            tps    MB_read/s    MB_wrtn/s    MB_read    MB_wrtn
nvme0n1       22701.50      2831.81         0.00       5663          0
nvme1n1       22709.00      2833.05         0.00       5666          0
nvme2n1       22727.50      2835.75         0.00       5671          0
sda               0.00         0.00         0.00          0          0
sdb               0.00         0.00         0.00          0          0
sdc               0.00         0.00         0.00          0          0
sdd               0.00         0.00         0.00          0          0
sde               0.00         0.00         0.00          0          0
sdf               0.00         0.00         0.00          0          0
dm-0              0.00         0.00         0.00          0          0
md0           68146.50      8501.58         0.00      17003          0

で、DB-Size = 353GB ÷ クエリ実行時間で算出したクエリ処理スループットは以下の通り。どんっ!

クエリ実行計画の作成やCUDAコンテキストの初期化、あるいは(直接GPUで高速化とはいかない)GpuHashJoinのハッシュ表作成なども含む総SQL実行時間ベースで、(クエリ毎のばらつきがあるとはいえ)7.0GB/s~7.5GB/s程度の処理スループットを発揮できている。

ただし、素直にこの結果を歓迎できないのが、PG-Stromを無効化した状態、つまり素のPostgreSQLのスコアが以前にBroadwell(E5-2650v4)機で計測したものと比べてずいぶん遅くなっているのである。
単体の能力では劣るIntel SSD 750の3枚構成でも2.0~2.2GB/s程度は出ていたので、ちょっと奇妙な結果ではある。

もしかすると、件のCPU投機実行に関わるLinux kernelパッチ適用の有無で変わったりもするのか?*2と思って、CentOS 7.4リリース時点のカーネル(当然、対策パッチは入ってない)に戻して同じベンチマークを走らせてみたりもしたが、このスローダウンを説明できるほどのデグレードではなかった。

ちょっとこのままだと説明資料に載せるのを躊躇ってしまう数字ではあるので、追って調査する事にしたい。誰かPostgreSQLに詳しい人のコメント大歓迎。

*1:ただ、以前にHGST SN260をお借りして評価した時にはP2P DMAで9.5GB/sまで出た実績があるが、その後再現条件が不明になってしまっており、純粋にH/Wの制約とも考えにくいところがある。

*2:PostgreSQLと比べ、PG-Stromは一度のシステムコールで要求するSSD-to-GPUのデータ転送サイズが大きく、相対的にシステムコール呼び出し回数が少なくなる。