Page-Locked Host Memory†ホストメモリにmalloc()やnewで領域を確保する代わりに, cudaMallocHost() や cudaHostAlloc() を使うとPage-locked host memoryを確保できます(解放はcudaFreeHost). このPage-locked host memoryを用いる利点は,
Page-lockedメモリは, cudaError_t cudaMallocHost(void ** ptr, size_t size); cudaError_t cudaHostAlloc(void ** ptr, size_t size, unsigned int flags); で確保することができます. ドライバはこの関数で割り当てられた仮想領域をトラックし, cudaMemcpyなどの命令が呼ばれたときに自動的に高速化してくれます. ただし,ホスト側でそのメモリ領域がページングされることも防いでおり, それによりシステム全体のパフォーマンスが低下する可能性もあるので, ホストとデバイス間で頻繁に転送があるデータのみに適用した方がよいです. それぞれ引数は,
flagsとしては,
を指定できます. cudaMallocHostはcudaHostAllocの最後の引数にcudaHostAllocDefaultを指定したものです. cudaHostAllocMappedを指定した場合,カーネルから直接ホストメモリにアクセスできます. これにより,デバイスメモリブロックを明示的に確保する必要がなく, ホストメモリブロックとデバイスメモリブロック間のデータ転送はカーネルにより必要に応じて 暗黙に実行されます.また,ストリームを使わなくてもデータ転送をオーバーラップさせることができます. デバイス側のアドレスを得るためにはcudaHostGetDevicePointer()を用いますが, そのためには,他のCUDA呼び出しが実行される前にcudaSetDeviceFlags()関数でcudaDeviceMapHostフラグをセットしておかなければなりません. また,cudaHostGetDevicePointer()はデバイスがデバイスがpage-lockedに対応していなくてもエラーを返すので, cudaGetDeviceProperties()でcanMapHostMemoryをチェックしておいた方がよいです. |