読者です 読者をやめる 読者になる 読者になる

GTCで喋りました

GPU 日常

という訳で、GTCで喋ってきました。

www.slideshare.net

今までの発表とは少し趣を変えて、PG-Stromそのものの説明よりも、現実世界のワークロードを実行するときにどういった使い方があり得るか、どういった効果が得られるかに主眼を置いた内容。

f:id:kaigai:20160408081720p:plain
伝統的にDBMSは、正に字面の通り、データベースをマネジメントするソフトウェアである訳なので、インデックスを張って目的のレコードを高速に取り出したり、テーブル同士を結合する事は得意だが、(一応SQLの構文で書く事はできるとはいえ)大量の計算をこなすには向いていない。
少なくとも、データ解析専用に設計されたツール(例えばR言語)を使って計算させた方が高速で、しかも統計解析系のパッケージも揃っているので、普通はデータベースからデータをエクスポートした上でデータ解析処理を行う。

では、PG-Stromを入れることで計算処理が早くなれば、この前提が変わるか?というのが今回のお題。

■ DB内で解析処理を行う事のメリット

  • サーバ~クライアント間でデータを移動せずにすむ。数GB単位の大きさになると無視できない。
  • 通常はクライアント側よりも強力なサーバハードウェアの計算能力を使用できる。
  • 常に最新のデータセットに対して解析処理を行うことができる。

■ DB内で解析処理を行うことのデメリット

  • サーバ側が十分な計算能力を持っている必要がある。
  • DBMSがデータ解析処理に対応するよう設計されている必要がある。
  • 専用APと比べると、ライブラリ類の整備が不十分。

ライブラリ類の充実はともかくとして、計算能力に関してはいかほどのものか。

f:id:kaigai:20160408081727p:plain

今回の実験のターゲットは、創薬に関連したワークロードの一つで、大量の化合物の中からできるだけ特性の異なった化合物を選択するというもの。これにより、実際に化合物を合成して特性を調べるなど、"お金のかかる" ステップを少なくしたいというモチベーションがある。

f:id:kaigai:20160408081740p:plain

使用したアルゴリズムはMAX-MIN法と呼ばれるもの。実際には何個かのクエリを繰り返し実行するのだが、ワークロードの中核、最も計算が重い部分は赤点線で囲った距離計算の部分。
化学物質の特性を数値パラメータ化し、比較対象との"距離"を計算する。
基本的にはこの距離が大きな化学物質を順に選択することで、ある一群からピックアップした k 個の化学物質の特性ができるだけ他と異なるものになる。

f:id:kaigai:20160408081748p:plain
これを、SQLによるデータエクスポート+R言語でのローカル計算、SQLで実行+R言語で結果参照 with/without PG-Strom の3パターンでそれぞれトライしてみた。
結果は、PG-Stromなしのパターンが圧倒的に遅く、R言語のローカル実行と、SQL+PG-Stromのリモート実行が概ね同じという結果になった。

そのため、現状でも『わざわざデータをEXPORTしてローカルで計算しなくても、SQLで全部計算させて結果だけ取ってきた方がデータ管理が楽ですよ』というのは言えるだろう。


一方で、他の並行セッションでは、よりHPCに近く計算能力を必要とする人工知能の研究成果が発表されており、『SQLを高速に処理する』がためにGPUを使用するPG-Stromの設計では専用にチューンしたアプリケーションに太刀打ちすることはできない。
(する必要があるのかどうか、という議論は当然あるが)

しかし、データに最も近い場所でCUDAプログラムを実行しうるプラットフォーム機能を既に有しているというアドバンテージを活かすのであれば、OLTP/OLAPという伝統的DBの世界から外れたところのワークロードについて考えてみる価値はあるだろう。おそらく、必要な要素技術は既に揃っている。

f:id:kaigai:20160408085151p:plain

検討してみたいのは、前回のエントリでも書いたアイデアで、CUDAのロジックをSQLで記述するための機能。

PostgreSQLでは、SQL関数を記述する言語を拡張モジュールによって定義する事ができる。
したがって、CUDAによって記述されたSQL関数を実現するのはそれほど難しい話ではない。

SQL上で hogehoge(matrix, vector) などと定義された関数であれば、実行時には、第一引数に行列をコピーしたバッファのポインタを、第二引数にベクトルをコピーしたバッファのポインタを渡すようにすればよい。フラットな単純配列に対してCUDAカーネルを起動すれば、あとは普通のHPC屋さんがやっている内容になる。

現状のSQL->CUDAへのコード変換の場合、SQLに由来するNULLチェックや四則演算の都度発生するオーバーフローチェックが入っているため、計算処理に重きを置くのであれば相当に効率の悪いコードになっている。

何から何までCUDAのコードを書かせるのはアレだが、R言語などでもパッケージ化されていて比較的良く使われる関数、例えば kmeans() 相当がCUDAのフルスピードで実行できるようになったらどうだろうか?

SQLでkmeans法のアルゴリズムを記述した場合、繰り返し処理の記述性が高くなく無駄な処理が入っていることもあり、現状では PG-Strom を用いてもRのkmeans()関数の1.5倍程度の時間を要している。(PG-Strom無しだと実行完了を諦めるレベルだが)

CUDAのフルスピードで行列演算を実行できれば、計算部分の処理速度を現状から更に一桁向上させる程度はできるだろう。
RDBMS的にはニッチもニッチでいい所の機能だが、『明らかに高速化の効果を実感できる』機能として、前倒しトライしてみるのも良いかなと思えてきた。