CUDA 6速報(1): Unified Memory

出典: トータル・ディスクロージャ・サイト(事実をありのままに)

先日発表されたCUDA 6について、NVIDIAが紹介している新機能をいくつか紹介する。なお、Toolkitはまだ評価できる状態ではないため、NVIDIAの紹介からの推測による記事である。そのため、正確性に欠ける可能性について気を付けたい。

目次

Unified Memoryとは

CPUとGPUとの両方からアクセスされることを目的としたメモリ領域である。CPUとGPUとの両方にメモリを確保し、データのコヒーレンシを保つように適宜同期が行われるような実装であると説明されている。

しばしば「CPUとGPUの両方のメモリにアプリケーションが直接アクセスできるようになる」というような表現で紹介しているニュースサイトがあるが、CPU上のメモリをGPUが直接アクセスする機能はすでにCUDA 2.2のときに「Mapped Memory」という機能で実現されている。さらに、CUDA 4.0のときに実装された「Unified Virtual Addressing」という機能はこれまでも「Mapped Memory」と混同されることが多かったが、名前の類似性から「Unified Memory」とも混同されることは十分に考えられる。以下、この3つの機能の区別を説明する。

Mapped Memory
GPUからアクセス可能なCPU上のメモリ。cudaHostAlloc等のAPIを使ってCPU上にMapped Memoryの領域を確保し、さらにGPU上のメモリ空間にこのMapped MemoryへアクセスするためのマッピングされたメモリアドレスをcudaHostGetDevicePointerで得て、このGPU上のメモリ空間アドレスを使ってGPUからアクセスする。
Unified Virtual Addressing
CPUのメモリ空間とGPUのメモリ空間の統一。従来のCPUプログラムで使われるライブラリは単一のメモリ空間を前提としたAPIが多く(たとえばMPIなど)、GPGPUプログラムとこれらのライブラリを併用しようとした場合、併用するためのリンク処理を書く末端プログラマにCPUとGPUとのデータ交換の負担がかかっていた。これを、ライブラリがCPUとGPUとのアドレスを既存のインターフェースを使って区別せずに受け取り、アドレスが示すデバイスの判定とデータ交換をCUDAのAPIを使ってライブラリ側で実装することで、末端のプログラマの負担を軽くすることができるのが大きなメリットである。これに併せて、先ほど紹介したMapped Memoryも、GPU上のメモリ空間にアドレスをマッピングすることなく、CPUで確保したアドレスをそのまま使えるようになっている。
なお、CUDA 3以前のMapped MemoryはcudaHostAllocを使って事前にMapped Memoryとしてアロケートされたメモリ領域のみ利用可能な機能であったのが、すでにアロケート済みのCPU上のメモリを後付けでMapped Memory化するcudaHostRegisterというAPIがUnified Virtual Addressing実装時に追加された。CPUのメモリアドレスをそのまま使えるようになったことで、Mapped Memoryの実装も柔軟なものとなったのだろうか。
Unified Memory
GPU上のメモリであるが、このアドレスをCPUからアクセスするとCPU上にバッファが確保されてGPUからデータが転送され、このバッファはGPUのKernel実行前にGPUへデータを転送して解放される。cudaMallocManagedという名前の新APIで確保されるらしい。Mapped MemoryはあくまでもGPUからCPU上のメモリへのアクセスであり、アクセスの度にCPUとGPUとの間の通信が発生する。一方Unified Memoryは、間にGPUの処理を挟まずにCPUが処理し続ける場合には通信は発生しないため、この通信の削減分が性能向上に寄与すると考えられる。

CUDA 6における実装としては次のようなものであると説明されている。GPU上のメモリのアドレスにCPUからアクセスすると、このアドレスはCPUのメモリに割り当てられていないのでPage Faultを起こす。その例外をトラップして、CPU上のメモリに新しいページを確保してこのアドレスに割り当て、この新しいページへGPUから対応するメモリ上のデータを転送する。そして、GPUが何か新しいKernelを実行する直前に、Unified Memoryの機構が割り当てたページをGPUに書き戻す。そして、GPUにデータを書き戻したページは解放される。

Unified Memoryはプログラムの記述を簡潔化する機能だと説明されがちな印象であるが、性能の劣化を我慢できるならすでにUnified Virtual Addressing対応のMapped Memoryでも同様の簡潔な記述は可能である。実際のところの最大のメリットは、CPUとGPUとの間での通信量をドライバで最低限度の量に最適化することによる高速化ではないだろうか。また、次世代のMaxwellアーキテクチャではUnified Memoryの制御がハードウェアに移ると言われていて、この最適化もさらに効率化されるのであろう。

CUDA 6.0 Release Candidate

以下、RC版を触って分かったUnified Memoryについての情報である。

対応環境

  • Compute Capability 3.0以上のGPU。
  • WindowsまたはLinux(ただしAndroidは除く)で、かつ64ビットOSである。

その他の細かい点として、Unified Memoryは複数プロセスで共有できない。特にUnified Memoryを確保した後プロセスをforkすると危険である。ただし、子プロセスがUnified Memoryに全くアクセスしない(たとえばfork直後に子プロセスがexecコールを行うなど)場合は安全であるとされている。

__managed__ 修飾子

従来の__host____device____shared____constant__修飾子に__managed__修飾子が追加。変数の実体がUnified Memory上に確保されることを表す。厳密には__device__修飾子の付いた変数に対して更に__managed__修飾子を追加した場合がUnified Memoryとなる仕様で、__managed__単体で使った場合は__managed__ __device__のシンタックスシュガーとなるとされている。今後のバージョンアップで__constant__変数に対しても__managed__修飾子を付けられるように計画されているようである。

ホスト上での__managed__変数やその参照の値は、CUDA Runtimeの初期化が完了し、正常なステートにある状態でのみ保障される。特にstatic変数のコンストラクタやデストラクタ中で__managed__変数を扱う場合、CUDA Runtimeの初期化より先にコンストラクタが呼ばれ、Runtimeの終了処理の後にデストラクタが呼ばれるようになるため、注意が必要である。

コヒーレンシのヒントの3モード

Unified Memoryのコヒーレンシの検査のヒントとして、cudaMemAttachGlobalcudaMemAttachHostcudaMemAttachSingleの3種類のモードが存在する。

cudaMemAttachGlobal
ホストおよびあらゆるStreamからアクセスの可能性があるというヒント。__managed__変数はこのモードとなる。
cudaMemAttachHost
アクセスの可能性があるのはホストだけで、GPUからのアクセスの可能性はないというヒントを与える。
cudaMemAttachSingle
アクセスの可能性があるのは、ホストの他には特定のStreamのKernelだけで、他のStreamのKernelからのアクセスの可能性はないというヒントを与える。「特定のStream」としてNull Stream (0)を指定することはできない。

Unified Memoryを動的に確保するAPIはcudaMallocManagedであるが、第1、第2引数はcudaMallocと同様であり、第3引数にcudaMemAttachGlobalcudaMemAttachHostのいずれか(cudaMallocManagedcudaMemAttachSingleを指定するのは不正)を指定する。C++では第3引数は省略でき、この場合はcudaMemAttachGlobalが指定された扱いとなる。

このモードはcudaStreamAttachMemAsync APIで上書きでき、こちらではcudaMemAttachSingleも指示できる。第1引数がStream、第2引数がUnfied Memoryへのポインタ、第3引数は0固定で、第4引数でモードを指定する。C++では第3、第4引数は省略でき、第4引数にcudaMemAttachSingleが指定された扱いとなる。cudaMemAttachSingleモードのときに対応するStreamが解放された場合は、メモリ確保時のモードに初期化される。

マルチGPU使用時の挙動について

GPUを跨いだUnified Memoryへのアクセスは、GPU間のZero Copyアクセスとして扱われる。Unified MemoryへのZero Copyアクセスは、Peerアクセスが有効なGPU同士では自動的にPeerアクセスとして扱われ、GPUDirectを用いた高速転送で処理される。


この記事へのコメントをお寄せください

  • サイトへの書き込みに差し支えございましたら トータルディスクロージャーサイトサポート係へメールをお送りください
  • トータル・ディスクロージャ・サイトに投稿された文章と画像は、すべてその著作権がHPCシステムズ株式会社に帰属し、HPCシステムズ株式会社が著作権を所有することに同意してください。
  • あなたの文章が他人によって自由に編集、配布されることを望まない場合は、投稿を控えてください。
  • コメントを書き込む場合は名前にひらがなを織り交ぜてください。
  • あなたの投稿する文章と画像はあなた自身によって書かれたものであるか、パブリック・ドメインかそれに類する自由なリソースからの複製であることを約束してください。あなたが著作権を保持していない作品を許諾なしに投稿してはいけません!

<comments hideform="false" />


Comments

ノート:CUDA 6速報(1): Unified Memory

個人用ツール