いくつか質問があります。
最近、CUDAを使ってプログラムを作っています。
私のプログラムでは、std :: map(string、vector(int))でプログラムされたホストに1つのビッグデータがあります。
これらのデータを使用することにより、一部のvector(int)がGPUグローバルメモリにコピーされ、GPUで処理されます
処理後、いくつかの結果がGPUで生成され、これらの結果がCPUにコピーされます。
これらはすべて私のプログラムスケジュールです。
- cudaMemcpy(...、cudaMemcpyHostToDevice)
- カーネル関数(カーネル関数は、必要なデータがGPUグローバルメモリにコピーされている場合にのみ実行できます)
- cudaMemcpy(...、cudaMemcpyDeviceToHost)
- 1〜3ステップを1000回繰り返す(別のデータ(ベクトル)の場合)
でも処理時間を短縮したいです。
そこで、プログラムでcudaMemcpyAsync関数を使用することにしました。
いくつかのドキュメントやWebページを検索した後、GPUにコピーするデータを持つcudaMemcpyAsync関数のホストメモリを使用するには、グローバルメモリを固定メモリとして割り当てる必要があることに気付きました。
しかし、私のプログラムはstd :: mapを使用しているため、このstd::mapデータを固定メモリに作成できませんでした。
したがって、これを使用する代わりに、バッファ配列型の固定メモリを作成しました。このバッファは、ベクトルをコピーするすべてのケースを常に処理できます。
最後に、私のプログラムはこのように機能しました。
- Memcpy(データ全体がバッファにコピーされるまで、ループを使用してstd :: mapからバッファにデータをコピーします)
- cudaMemcpyAsync(...、cudaMemcpyHostToDevice)
- カーネル(カーネル関数は、データ全体がGPUグローバルメモリにコピーされた場合にのみ実行できます)
- cudaMemcpyAsync(...、cudaMemcpyDeviceToHost)
- 1〜4ステップを1000回繰り返す(別のデータ(ベクトル)の場合)
そして、私のプログラムは前のケースよりもはるかに速くなりました。
しかし、問題(私の好奇心)はこの時点にあります。
同様の方法で別のプログラムを作成しようとしました。
- Memcpy(std :: mapから1つのベクトルのバッファーにのみデータをコピーします)
- cudaMemcpyAsync(...、cudaMemcpyHostToDevice)
- データ全体がGPUグローバルメモリにコピーされるまでループ1〜2
- カーネル(カーネル関数は、必要なデータがGPUグローバルメモリにコピーされている場合にのみ実行できます)
- cudaMemcpyAsync(...、cudaMemcpyDeviceToHost)
- 1〜5ステップを1000回繰り返す(別のデータ(ベクトル)の場合)
この方法は、上記の方法よりも約10%高速であることがわかりました。
でも理由はわかりません。
cudaMemcpyAsyncはカーネル関数とのみオーバーラップできると思います。
しかし、私の場合はそうではないと思います。cudaMemcpyAsync関数間でオーバーラップできるように見えるのではなく。
長い質問で申し訳ありませんが、その理由を本当に知りたいです。
誰かが私に正確な機能「cudaMemcpyAsync」とは何か、そしてどの機能を「cudaMemcpyAsync」とオーバーラップできるかを教えたり説明したりできますか?