4

カーネル起動操作の仕組みに関する情報はあまり見つかりません。APIは、 CudaProgGuideを参照すると言います。そして、私もそこに多くを見つけていません。
カーネルの実行は非同期であり、一部のマシンは同時実行をサポートしているため、カーネルのキューがあると思われます。

    Host code:      
    1. malloc(hostArry, ......);  
    2. cudaMalloc(deviceArry, .....);  
    3. cudaMemcpy(deviceArry, hostArry, ... hostToDevice);
    4. kernelA<<<1,300>>>(int, int);  
    5. kernelB<<<10,2>>>(float, int));  
    6. cudaMemcpy(hostArry, deviceArry, ... deviceToHost);  
    7. cudaFree(deviceArry);

3 行目は同期です。4 行目と 5 行目は非同期で、マシンは同時実行をサポートしています。したがって、ある時点で、これらのカーネルは両方とも GPU 上で実行されます。(kernelA が終了する前に、kernelB が開始および終了する可能性があります。) これが発生している間、ホストは行 6 を実行しています。 kernelB が終了しました。

1) GPU にカーネル キューはありますか? (GPU はホストをブロック/ストールしますか?

4

2 に答える 2

4

はい、GPU にはさまざまなキューがあり、ドライバーがそれらを管理します。

非同期呼び出しは、多かれ少なかれすぐに戻ります。同期呼び出しは、操作が完了するまで返されません。カーネル呼び出しは非同期です。他のほとんどの CUDA ランタイム API 呼び出しは、Async非同期の場合、サフィックスによって指定されます。あなたの質問に答えるには:

1) GPU にカーネル キューはありますか? (GPU はホストをブロック/ストールしますか?)

さまざまな待ち行列があります。GPU は同期呼び出しでホストをブロック/ストールしますが、カーネルの起動は同期操作ではありません。カーネルが完了する前、おそらくカーネルが開始する前に、すぐに戻ります。操作を単一のストリームに起動すると、そのストリーム内のすべての CUDA 操作がシリアル化されます。したがって、カーネルの起動は非同期ですが、CUDA サブシステムは、ストリーム内の特定の CUDA 操作が同じストリーム内の以前のすべての CUDA 操作が開始されるまで開始されないことを保証するため、同じストリームに対して起動された 2 つのカーネルの実行が重複することはありません。終了しました。null ストリーム (コードでストリームを明示的に呼び出さない場合に使用するストリーム) には、他にも特定のルールがありますが、この質問を理解するには、上記の説明で十分です。

2) ホストはカーネルが終了したことをどのように認識し、結果をデバイスからホストに転送しても「安全」ですか?

デバイスからホストに結果を転送する操作はCUDA呼び出し (cudaMemcpy...) であり、前の操作と同じストリームで発行されるため、デバイスとCUDA ドライバーは cuda 呼び出しの実行シーケンスを管理して、 cudaMemcpy は、同じストリームに対して発行された以前のすべての CUDA 呼び出しが完了するまで開始されません。したがって、cudaMemcpy同じストリームでカーネル呼び出しの後に発行された は、 を使用しても、カーネル呼び出しが完了するまで開始されないことが保証されていますcudaMemcpyAsync

于 2013-07-14T01:44:47.947 に答える
0

カーネル呼び出しの後にcudaDeviceSynchronize()を使用して、デバイスに要求された以前のすべてのタスクが完了したことを保証できます。kernelB の結果が kernelA の結果から独立している場合は、メモリ コピー操作の直前にこの関数を設定できます。そうでない場合は、kernelB を呼び出す前にデバイスをブロックする必要があり、2 つのブロック操作が発生します。

于 2012-10-05T20:57:31.917 に答える