AtomicやマルチGPUの使い勝手も改善

Atomicなメモリアクセスであるが、Pascal以前のGPUでは、1つのGPUの中では有効であるが、システムメモリや他のGPUのGPUメモリのアクセスのアトミック性は保証されていなかった。

これに対してPascalでは、NVLINKで接続されているハードウェアの場合はアトミック性が保証され、PCI Express接続の場合もソフトウェアサポートでアトミック性を実現するという。

Pascalではアトミックも強化され、NVLINK接続のハードウェア全体でアトミックアクセスが実現される

Pascalでは、CPUとGPU間のページ移動と同様なメカニズムで、複数GPUを使うシステムでもページフォールトをトリガーとしたGPU間のページの移動が可能になる。

PascalではCPU、GPU間のページ移動と同様なメカニズムで、複数GPUを使うシステムでGPU、GPU間のページ移動が可能になる

双方向のオンデマンドページングは効果絶大

Pascal以前のGPUでは、すべてのデータをGPUメモリに置く必要があったため、サイズの大きいグラフを扱うことは難しかった。しかし、Pascalではオンデマンドのページ移動が可能になったので、必要となった時点で、その頂点と辺のデータを自動的にシステムメモリから持ってくるという処理ができる。

大きなグラフのすべての頂点と辺のデータをGPUメモリに入れるのは時間がかかるが、処理によっては、グラフの一部の頂点と辺のデータだけが使われ、大部分のデータは使われないというもったいないことが起こる。しかし、デマンドページングの場合は必要になった時点で、そのデータを含むページだけを移動してくるので、大きな無駄は発生しない。

次の図は、グラフのMaximal Flowを求める例で、辺に付けられた数字は分母がその辺の輸送容量、分子は実際に流れる輸送量で、最初は分子はすべてゼロの状態から処理を開始する。

Maximum FlowはSourceからSinkに向かって流せる最大量を求める問題で、辺に付けられている分母の数字は、その辺が流せる最大量で、分子は実際に流す量。最初は分子は全て0であるが、ここでは処理の進んだ状態の数字が入っている

最大輸送量を求めるアルゴリズムは、 BFS(Breadth First Search)でソースから辺で直接繋がっている頂点をすべて見つけ、それらの頂点からグラフを逆にたどってどれだけ量の輸送ができるかをアップデートして行くという作業を繰り返す。

しかし、GPUメモリに入らない大きなグラフの場合、Unified Memoryを使わずにこのアルゴリズムの実装するのは、非常に困難であるという。

Maximum Flowを求めるEdmonds-Karpのアルゴリズムの疑似コード。Unified Memoryが使えないと、このアルゴリズムの実装は非常に面倒である

このMaximum Flowを求める処理を色々な状況で行った場合の性能を比較したのが次のグラフである。ここでは、GPUがPCI Express経由でCPUメモリを直接アクセスして処理を行う場合の性能を1.0とする。そして青の棒グラフは最初にGPUがアクセスした時に、オンデマンドページングでGPUメモリにページを移動して処理するUnified Memoryの場合の性能、赤の棒グラフは人間がデータの配置を最適化した場合の性能を示している。

横軸は、GPUメモリの容量の何倍の量のメモリを使っているかで、一番左はGPUメモリの半分、次は90%を使用している場合で、右側の2つは、120%、150%と実メモリより大きなメモリを必要とするケースである。

必要メモリ量が実メモリ量より少ないケースでは、PCI Express経由のアクセスの3倍以上の性能が得られ、人間がデータ配置を工夫したケースとUnified Memoryでオンデマンドのページ移動を使うケースの性能の差はほとんど無い。実メモリより大きなメモリを使うケースでは人手の最適化より性能は下がるが、それでもUnified Memoryを使うとPCI Express経由のアクセスの1.7~1.8倍の性能が得られる。また、このケースでは人手による最適化を行ったケースとの性能差がかなりあるが、実メモリに対して使用メモリ量が多くなるにつれて差は小さくなる傾向があり、実メモリの何倍もの大きなメモリを使用するケースでは大きな差は無くなるのではないかと予想されるという。

Maximum Flowの実行にオンデマンドページングを使うと、使用メモリが実メモリより小さい場合は、PCI Express経由のアクセスの3倍強。使用メモリが実メモリより大きくページの入れ替えが発生する場合でも1.7倍程度の性能が得られる

Pascalではデマンドページングが可能になったので、GPUの実メモリより大きなメモリを必要とする(GPU Oversubscription)問題を扱うことができるようになった。デマンドページングが無ければ、GPUメモリに収まるように問題を分割したり、データの入れ替えを行なったりすることが必要になり、プログラムがずっと複雑になってしまう。エンジンなどの燃焼の計算、量子化学、レイトレーシングなどではこのOversubscriptionは大きな効果がある。

デマンドページングは、GPUメモリに収まらない計算を可能にする。これはエンジンなどの燃焼の計算、量子化学、レイトレーシングなどで、プログラミングを大幅に容易にする

デマンドページングを使ってOversubscriptionを行うとページの入れ替えが必要になり性能が低下するのではないかという懸念があるが、マルチグリッドのベンチマークのHPCMGでの性能がどのようになるかを示したのが次の図である。実GPUメモリが12GBのTesla K40を使った場合は総メモリ使用量が8GB程度までしか動作しないが、デマンドページングを行うTesla P100では性能のピークは実メモリ量を超える20GB程度のメモリ使用まで伸び、更に実メモリを大きく上回るメモリを使用する場合でも、K40の最大性能を上回っている。

縦軸に性能、横軸にメモリに使用量を取って、Tesla K40とPascalアーキテクチャのP100 GPUを比較した。実GPUメモリより大きなメモリを必要とするケースでもP100の方が性能が高いことが分かる

ソートを行なったりして、複数のキューを作るという処理は珍しくない。そして、それぞれのキューの長さがどうなるのかはデータ依存であり実行前には不明であるので、それぞれのキューの長さの上限は、ある程度余裕を持ってメモリを割り付けて置くことが必要になる。

しかし、すべてのキューで最大の長さになることは無いので、次の図の赤色のページは使われるが、灰色のページは割り付けられてはいるが使われていないということになり、無駄になっている。

複数のキューにソート結果を格納する処理では、普通は各キューの最大エントリ数が収容できるメモリを用意して置く必要があり、使われない無駄なメモリが多くなる

これをオンデマンドページングを使うと、各キューでメモリが必要になった時点でページを追加すれば良く、無駄になるのはそれぞれのキューについて1ページ分のメモリを越えない。

オンデマンドページングでは、エントリの追加が必要になった場合は、そのキューを延長するために1ページを追加するだけで良く、無駄なメモリ割り当てを最小にできる

デマンドページングのサポートはGPUのハードウェアの変更という点では、それほど大きな変更ではないが、CPU、GPUの双方からデマンドページングができるようになったので、CPU、GPU間のデータの転送を明示的に書かず、デマンドページングに任せてしまうことができるようになった。これは、GPUプログラミングの簡単化という点では非常に大きな改善である。

また、デマンドページングを使うOversubscriptionで、データを分割して処理するような特別なプログラミングを行うことなく、実GPUメモリより大きなGPUメモリを使う問題を扱うことができるようになった。これは、GPUに搭載された実メモリのサイズの制約をあまり気にせず、プログラムを書くことができるようになったことを意味しており、これもプログラミングの負担を下げる効果がある。

ただし、ページフォールトの処理とページの移動には数10μsを必要とするので、過度のページ移動が起こらないように注意する必要がある。