Cuda探测器说我的两个内核很昂贵,但是它们的执行时间似乎很小

时间:2013-05-15 12:19:25

标签: performance cuda kernel profiler

我使用了两个内核,我们称之为AB

我运行CUDA探查器,这就是它返回的内容:

enter image description here

第一个内核有44%的开销,而第二个内核有20%。

但是,如果我决定按照这个逻辑找出实际执行时间:

timeval tim;
gettimeofday(&tim, NULL);
double before = tim.tv_sec+(tim.tv_usec/1000000.0);

runKernel<<<...>>>(...)

gettimeofday(&tim, NULL);
double after=tim.tv_sec+(tim.tv_usec/1000000.0);
totalTime = totalTime + after - before;

totalTime非常小,约为0.0001秒。

我是CUDA的新手,我并不清楚究竟发生了什么。我应该尝试使内核更有效率还是已经有效?

1 个答案:

答案 0 :(得分:3)

从CPU的角度来看,内核调用是异步的(参见this answer)。如果你按照你没有任何同步的方式计算你的内核(即没有调用cudaDeviceSynchronize()),你的计时并不意味着什么,因为GPU上的计算仍在进行中。

在计算内核时,您可以信任NVIDIA的分析器(nvprof / nvvp)。 NVIDIA Visual Profiler还可以分析您的程序并提供有关内核可能出错的一些建议:uncoalesced memory accesses,分配的线程/块数量不足等。您还需要在发布模式下编译代码优化标志(例如-O3)以获得一些相关的时间。

关于内核优化,您需要找到瓶颈(例如您的44%内核),分析它并应用通常的optimization techniques

  
      
  • 使用设备的有效带宽来确定内核的性能上限应该是什么
  •   
  • 最大限度地减少主机和设备之间的内存传输 - 即使这意味着在设备上进行无效的计算
  •   
  • 合并所有内存访问
  •   
  • 首选共享内存访问全局内存访问
  •   
  • 避免代码执行在单个warp中分支,因为这会序列化线程
  •   

您也可以使用指令级并行(您应该阅读these slides)。

然而,很难知道何时无法再优化内核。说内核的执行时间很短并不意味着:与什么相比较小?你想做一些实时计算吗?可伸缩性是一个问题吗?这些是在尝试优化内核之前需要回答的一些问题。

另外,您还应广泛使用error checking,并依靠cuda-memcheck / cuda-gdb来调试您的代码。