Kepler GPUでのUnified Memoryの問題

それは、x86 CPUの1ページは4KBであるのに対して、NVIDIAのGPUの1ページは8KBであったからである。前の例のように、GPUにあるページをCPUに移す場合はGPU側のページテーブルエントリをInvalidに変えれば、その8KBページへのGPUのアクセスを禁止することができる。しかし、逆にCPU側にあるページをGPUに移す場合は、CPUのページは4KBであるので、2つのページテーブルエントリを同時にInvalidにする必要がある。この「同時にInvalid」がx86 CPUでは行えない。

このため、CUDA 6では、CPUはアクセス要求を出せば、そのVAを含む8KBページがGPUから移動されるが、その逆はできないということになっている。

そのため、Pascal以前のGPUでは、CPUのシステムメモリからGPUメモリへのデータの移動は、GPUでカーネルを起動する前に行っておく必要がある。これは、カーネルが必要とするすべてのメモリをGPUメモリに確保して置く必要があるということである。

Pascal以前のGPUでは、GPUカーネルが使う全部のメモリを確保し、必要なデータはカーネルの実行開始の前にGPUメモリに入れて置く必要があった

この状況を図示したのが次の図で、GPUメモリにありシステムメモリにはないデータをCPUがアクセスするとページフォールトが発生して、そのページをPCI Express経由で、GPUメモリからシステムメモリに自動的に移動する。

CPUのページフォールトに対応してGPUメモリからシステムメモリにページを移動する

Pascalでは双方向のページ移動が可能になった

Pascal GPUでは、GPUのメモリアクセスがページフォールトを起こした場合、逆方向のシステムメモリからGPUメモリへのページの移動ができるようになった。

このため、カーネルが必要とするデータがシステムメモリにあったとしても、カーネルが起動されると、そのデータをアクセスし、システムメモリからGPUメモリへのページの移動が自動的に行われる。

そのため、カーネル起動の前にGPUメモリに必要なデータを入れて置くという必要性が無く、プログラミングがずっと楽になる。

Pascal GPUではシステムメモリからGPUメモリへのデマンドページングがサポートされ、カーネル起動の前にすべてのデータをGPUメモリに入れておくという必要が無くなった

Pascalでは、GPU側のページフォールトでシステムメモリからGPUメモリへのページの移動ができるようになり、双方向のページ移動ができるようになった。また、PascalではPCI Expressより高速なNVLINKがサポートされ、NVLINKをサポートするPOWER CPUが出てくれば、より高速にページの移動ができるようになる。

Pascal GPUではGPU側のページフォールトでシステムメモリからGPUメモリへのページ移動ができるようになった

この後に述べるように、双方向のデマンドページングができるようになり、使い勝手が向上するのであるが、このために、PascalでNVIDIAが行ったのは、Pascal GPUのページサイズを4KBにしてx86 CPUと同じにするという変更である。ページサイズが同じであるので、CPU側で2つのページテーブルエントリを同時にInvalidにする必要が無くなったので、これが可能になった。

このために必要となるハードの変更は僅かであるが、8KBページを前提として作られているコードがあると動かなくなってしまう可能性があるので、過去のGPUコードをチェックして必要に応じて修正を行うというのは、大変な作業であったのではないかと思われる。

しかし、その結果、双方向のオンデマンドのページ移動が可能になり、必要となった時点でシステムメモリからデータを持ってくることができるので、GPU側にカーネルが使うすべてのメモリを確保して置く必要が無くなった。このため、GPUメモリの容量より大きなメモリを必要とするカーネルを実行することができるようになった。

また、CPUとGPUのメモリの間でページ粒度のコヒーレンシが保たれるようになり、使い勝手が向上した。

双方向のオンデマンドのページ移動が可能になり、すべての必要なデータをGPUメモリに準備してからカーネルを起動する必要が無くなった