CUDAでは、ピン留めされたメモリを使用して、ホストでmallocを介して割り当てられたデフォルトのメモリよりも効率的にデータをホストからGPUにコピーできます。ただし、ピン留めされたメモリには、デフォルトのピン留めされたメモリとゼロコピーのピン留めされたメモリの2種類があります。
デフォルトの固定メモリは、通常の転送の2倍の速度でホストからGPUにデータをコピーするため、間違いなく利点があります(ページロックするのに十分なホストメモリがある場合)
固定されたメモリの異なるバージョン、つまりゼロコピーメモリでは、データをホストからGPUのDRAMに完全にコピーする必要はありません。カーネルは、ホストメモリから直接データを読み取ります。
私の質問は、これらの固定メモリタイプのどれがより良いプログラミング手法であるかということです。
それはあなたのアプリケーションに依存すると思います(そうでなければ、なぜ彼らは両方の方法を提供するのでしょうか?)
マップされ、固定されたメモリ(ゼロコピー)は、次のいずれかの場合に役立ちます:
GPUにはそれ自体にメモリがなく、とにかくRAM
データを1回だけロードしますが、実行する計算が多く、データを介したメモリ転送の待ち時間を隠したいと考えています。
ホスト側は、カーネルがまだ実行されている間に、データを変更/追加したり、結果を読み取ったりしたいと考えています(通信など)
データがGPUメモリに収まらない
複数のストリームを使用してデータをコピーし、カーネルを並行して実行することもできることに注意してください。
ピン留めされていますが、マップされていないメモリの方が優れています:
データを複数回ロードまたは保存する場合。例:後続のカーネルが複数あり、段階的に作業を実行します。毎回ホストからデータをロードする必要はありません。
実行する計算はそれほど多くなく、読み込みの待ち時間はうまく隠されません
マップされたピン留めメモリは、CUDAアドレス空間にマップされることを除いて、すべての点で他のタイプのピン留めメモリと同じであるため、CUDAカーネルによる読み取りと書き込み、およびDMAコピーエンジンによる転送。
ピン留めされたメモリをマッピングしないことの利点は2つあります。アドレス空間を節約できます。これは、3〜4GのRAMを保持できるGPUを備えた32ビットプラットフォームの世界で貴重な商品になる可能性があります。また、マップされていないメモリは、不正なカーネルによって誤って破損することはありません。しかし、その懸念は難解であるため、CUDA 4.0の統合アドレス空間機能により、固定されたすべての割り当てがデフォルトでマップされます。
Sanders/Kandrotの本で提起された点に加えて、覚えておくべき他の事柄:
カーネルからホストメモリへの書き込み(たとえば、結果をCPUに投稿するため)は、GPUにその場合をカバーするレイテンシがないという点で優れています。
メモリ操作を統合することは非常に重要です。そうしないと、SM2.x以降のGPUでさえ帯域幅に大きな打撃を与えます。