PGI 17.7リリースでは、allocatable として割り付けられたデータ用の CUDA Unified Memory の使用がベータ版からプロダクション版に移行しました。 この機能は、 OpenACC および CUDA Unified Memory PGInsider の記事で詳しく説明されており、Linux/x86-64 および Linux/OpenPOWER コンパイラで利用できます。 Linux/x86-64 では、デフォルトの PGI コードジェネレータと Beta版 LLVMベースのコードジェネレータの両方を使用してサポートされています。 この機能を有効にするには、オプション -ta=tesla:managed をコンパイラおよびリンカのコマンドラインに追加します。
-ta=tesla:managed の場合、プログラム単位内のすべての C/C++、Fortran の明示的な allocate 文は、CUDA Unified Memory 上にデータを配置する同等の「管理された」データ割り当て呼び出しに置き換えられます。 管理対象データは CPU/GPU の単一アドレスを共有し、CPU と GPU メモリ間のデータ移動は CUDAドライバによって暗黙的に処理されます。 したがって、OpenACC のデータ句とディレクティブは、「管理された」データには必要ありません。 それらは本質的に無視され、実際には省略することができます。
プログラムが管理されたメモリを割り当てると、デバイスのメモリだけでなくホストの固定メモリも割り当てられます。したがって、割り当てと解放の操作がやや高価になり、データの転送がやや高速になります。 メモリプールアロケータは、アロケートおよびフリーオペレーションのオーバーヘッドを軽減するために使用されます。プールアロケータは -ta=tesla:managed または -ta=tesla:pinned に対してデフォルトで有効になっています。 PGI 17.7リリースでは、 -Mcuda が存在するとプールアロケータが無効になります。 今後のリリースでその制限を解除する作業を進めています。
管理データのデータ移動は、NVIDIA CUDA GPUドライバによって制御されます。 CPU または GPU 上でデータにアクセスするたびに、最後にアクセスされたときに同じデバイス上にデータが転送される可能性があります。 場合によっては、ページのスラッシングが発生し、パフォーマンスに影響を与えることがあります。 Parallel Forall では、CUDA Unified Memory の概要を紹介しています。
この機能には次の制限があります。
この機能には、NVIDIA Kepler GPU で 使用するときに次の追加制限があります。
この機能は、NVIDIA Fermi GPU ではサポートされていません。
CUDA Unified Memory Pool Allocator
動的メモリ割り当ては、cudaMallocManage() を使用して行われます。このルーチンは、cudaMalloc()を使用して非ユニファイドメモリを割り当てるよりもオーバーヘッドが高いルーチンです。 cudaMallocManaged() の呼び出し回数が増えるほど、パフォーマンスへの影響が大きくなります。
cudaMallocManaged() 呼び出しのオーバーヘッドを軽減するために、-ta=tesla:managed および -ta=tesla:pinned は CUDA Unified Memory プールアロケータを使用して、cudaMallocManaged() への呼び出し回数を最小限に抑えます。 プールアロケータは、デフォルトで有効になっています。次の環境変数を使用して無効にするか、動作を変更できます。
PGI_ACC_POOL_ALLOC | プールアロケータを無効にします。 プールアロケータはデフォルトで有効になっています。 無効にするには、PGI_ACC_POOL_ALLOCを0に設定します。 |
PGI_ACC_POOL_SIZE | プールのサイズを設定します。 デフォルトのサイズは1GBですが、他のサイズ(2GB、100MB、500KBなど)を使用できます。 実際のプール・サイズは、フィボナッチ・シリーズのサイズが、提供されたサイズまたはデフォルトサイズと比較して、最も近い、より小さい数になるように設定されます。 必要であれば、プールアロケータはプールを追加しますが、PGI_ACC_POOL_THRESHOLD値までしか追加しません。 |
PGI_ACC_POOL_ALLOC_MAXSIZE | 割り当ての最大サイズを設定します。 割り当てのデフォルトの最大サイズは64Bですが、16B以上であれば別のサイズ(つまり100KB、10MB、250MBなど)を使用できます。 |
PGI_ACC_POOL_ALLOC_MINSIZE | 割り当てブロックの最小サイズを設定します。 デフォルトサイズは16Bですが、他のサイズを使用することもできます。 サイズは16B以上でなければなりません。 |
PGI_ACC_POOL_THRESHOLD | プールアロケータが占めることができるデバイスメモリの合計の割合を設定します。 デフォルトは50%に設定されていますが、他のパーセンテージを使用することもできます。 |