GTCに来ています

今年もサンノゼで開催されている GPU Technology Conference 2016 に参加しています。

# なお、当方の発表『In-Place Computing on PostgreSQL: SQL as a Shortcut of GPGPU』は木曜日の予定

f:id:kaigai:20160405081234j:plain
キーノートでは、NVIDIA社CEOのJen-Hsum Huang氏より"ディープラーニング向けプロセッサ"と銘打って、新アーキテクチャPascalを搭載したTesla P100が発表に。また、CUDA8.0のリリースが6月である事も発表された。
(一方で、事前に噂されていたPascalベースのコンシューマ向けGTXモデルへの言及はなかった)

f:id:kaigai:20160405102340j:plain

このPascalアーキテクチャベースのTesla P100であるが、Inside Pascal: NVIDIA’s Newest Computing Platformに記載のある通り、

...等々のお化けプロセッサである。

プログラムを書く上で、Maxwell世代から変わっている点、新機能が追加になった点がある。

  • SM(Streaming Multiprocessor)あたりのCUDA Core数が減っている

128個 -> 64個になった。一方でSM数は56個に増えており、これでトータル3584CUDA Coreという訳だが、SMあたりのレジスタファイル容量(256KB)は据え置き、共有メモリ容量(64KB)は33%増加*1であるので、システム全体として見ると、大幅な増強となっている。

また、SMあたりのコア数が少なくなった一方で、レジスタ、共有メモリの容量が据え置きになっているという事は、ある特定のSMに対して一度に投入できるタスクの数が増え、それにより、例えばDRAMアクセス待ちの間に他のタスクにスケジュールして計算コアの使用率を上げる事ができると思われる。

PG-Stromのようにnone-coalescedなメモリアクセスが多いワークロードでは嬉しいかも。

PG-Stromには嬉しい新機能。現状、PostgreSQL数値計算系の関数は全て64bit浮動小数点で、標準偏差や分散、共分散などを集計する時には、内部的には cmpxchg 命令を使った atomic 演算のエミュレーションを行わざるを得ないので、H/Wによりネイティブの atomic 演算がサポートされれば集計系の性能向上が期待できる。

  • プリエンプションの対応

仮想化環境での利用を見込んだ機能か?上述のSMに投入できるブロック数が増えたという事も併せて考えると、Pascal世代ではGPUの同時並行利用が大いに促進されるような気がする。

  • デマンドページング

従来は、予め必要となるバッファサイズを予測してCUDA Kernelを起動する前にデバイスメモリのアロケーションが必要であったが、これにはある程度マージンを取る必要があるので、実際には無駄になる領域が少なからずあった。GPU側でもPage Fault→デバイスメモリ割当てという流れが可能になる事で、リソースの有効利用が可能となる。
一方で、Page Faultのコストは無視できないほど高いので、cudaMemPreFetchAsync()などCUDA8.0で対応となる新APIにより、プログラムがヒントを与えてやる必要がある。

  • HBM2

一目で分かるように、スループットが大幅に引き上げ。現行世代の3倍弱。
ただし、これはメモリアクセスがcoalescedな場合の性能向上で、none-coalescedなメモリアクセスはレイテンシが律速要件になるため、現行世代と比較して10%程度の向上との事。

行指向データ構造を使うPG-Stromとしてはちょっと悲しい所だが、対策としては、例えばDRAMからデータを一旦共有メモリにロード(ここはcoalescedなアクセスで)。その後の共有メモリへのアクセスはL1キャッシュと同じレイテンシなので、そんなに気にはならないはず。

SMあたりのCUDAコア数が減った事で、こういう最適化も考えられる。


さて、会場でSさんとHさんに『PG-Stromの上でMachine Learningのアプリとか動かせるようにならないんですかね~?』と無茶振りをされる。

現状、"PostgreSQLと同じ使用感"で使える事を優先するために、本来は効率の悪い行指向データをリッチな計算リソースで無理やり並列処理しているので、専用のアプリケーションでの処理と比べるとどうしても分が悪い。

ただ『データのある場所で計算を行う』というのは正しい方向性なので、SQLで数式を書いたら自動的にコード生成⇒GPU実行、という流れに拘らなければ、SQLクエリ実行の過程でデータ密度の高いデータ構造を作り出し、これをGPUで実行するMachine Learning用の(でも、何か他の数値計算の)アプリケーションに渡してやるという事はそんなに不自然ではないのかな、とは思う。

例えば、32bit浮動小数点型の2次元配列・NULLなしというデータ構造であればぎっしりデータが詰まっており、先頭からのオフセットだけでアクセスすべきデータを特定できる。つまり、行指向ならではの不都合はない。これを仮に matrix 型と名付けて、

SELECT my_deep_leraning(SELECT make_matrix(x0, x1, x2, ..., xN)
                          FROM data_source
                         WHERE 抽出条件
                         GROUP BY グループ化条件);

みたいなクエリで実行できれば、、、、って事にはなるだろう。

ただ、当然に考えねばならん課題もあり、
・生成するMATRIXがGPUのRAMサイズに収まらない場合
・粗行列の場合、本当に単純な配列表現でいいのか?
・一行に対して複数のCUDA Kernelで処理する事になるので、PG-Stromにとってはwhat's new

面白いアイデアなので、もう少し考えてみたいところではある。

*1:たぶんブロックあたりのサイズの事を言っている。SMあたり容量ならMaxwellの上の方は96KBなので