3

CUDA 中的内核启动通常是异步的,这(据我所知)意味着一旦启动 CUDA 内核,控制就会立即返回给 CPU。当 GPU 忙于处理数字时,CPU 会继续做一些有用的工作,除非 CPU 使用cudaThreadsynchronize()或强制停止cudaMemcpy()

现在我刚刚开始使用 CUDA 的Thrust库。Thrust 中的函数调用是同步的还是异步的?

换句话说,如果我调用thrust::sort(D.begin(),D.end());where D is a device vector,那么使用来测量排序时间是否有意义

        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 推力使用一样。

因此,您的示例只会测量内核启动和推力主机端设置开销,而不是操作本身。对于计时,您可以通过在推力内核启动后调用cudaThreadSynchronizecudaDeviceSynchronize(在 CUDA 4.0 或更高版本中)来解决此问题。或者,如果您包含内核启动后复制操作并在此之后记录停止时间,您的时间将包括设置、执行和复制时间。

在您的示例中,这看起来像

   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 回答