3

CUDA でのカーネルの起動は一般に非同期です。これは、(私が理解しているように) CUDA カーネルが起動されるとすぐに制御が CPU に戻ることを意味します。cudaThreadsynchronize()またはを使用して CPU を強制的に停止させない限り、GPU が数値計算でビジー状態の間、CPU はいくつかの有用な作業を続けcudaMemcpy()ます。

CUDA 用のThrustライブラリを使い始めたところです。Thrust の関数呼び出しは同期ですか、それとも非同期ですか?

言い換えれば、thrust::sort(D.begin(),D.end());D がデバイス ベクトルである場合、次を使用して並べ替え時間を測定することは理にかなっていますか?

        start = clock();//Start

             thrust::sort(D.begin(),D.end());

        diff = ( clock() - start ) / (double)CLOCKS_PER_SEC;
        std::cout << "\nDevice Time taken is: " <<diff<<std::endl;

関数呼び出しが非同期の場合、どのベクトルでも diff は 0 秒になりますが (これはタイミングのジャンクです)、同期の場合は実際にリアルタイムのパフォーマンスが得られます。

4

1 に答える 1

4

カーネルを呼び出す推力呼び出しは、基礎となる CUDA API の推力が使用するのと同じように非同期です。基礎となる CUDA API のスラストが使用するのと同じように、データをコピーするスラスト呼び出しは同期的です。

したがって、あなたの例は、操作自体ではなく、カーネルの起動とスラストのホスト側セットアップのオーバーヘッドのみを測定することになります。タイミングについては、スラスト カーネルの起動後にcudaThreadSynchronizeor (CUDA 4.0 以降では後者)を呼び出すことで、これを回避できます。cudaDeviceSynchronizeまたは、カーネル起動後のコピー操作を含め、その後の停止時間を記録すると、タイミングにはセットアップ、実行、およびコピーの時間が含まれます。

あなたの例では、これは次のようになります

   start = clock();//Start 

   thrust::sort(D.begin(),D.end()); 
   cudaThreadSynchronize(); // block until kernel is finished

   diff = ( clock() - start ) / (double)CLOCKS_PER_SEC; 
   std::cout << "\nDevice Time taken is: " <<diff<<std::endl; 
于 2011-11-11T08:20:00.310 に答える