0

我使用两个内核,我们称它们AB.

我运行 CUDA 分析器,它返回的是:

在此处输入图像描述

第一个内核有 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 的新手,我不明白到底发生了什么。我应该尝试使内核更高效还是它们已经高效?

4

1 回答 1

3

从 CPU 的角度来看,内核调用是异步的(请参阅此答案)。如果您按照没有任何同步(即没有调用cudaDeviceSynchronize())的方式对内核进行计时,那么您的计时将没有任何意义,因为计算仍在 GPU 上进行。

nvprof在为内核 ( / )计时时,您可以信任 NVIDIA 的分析器nvvp。NVIDIA Visual Profiler 还可以分析您的程序,并就您的内核可能出现的问题提供一些建议:未合并的内存访问、分配的线程/块数无效等。您还需要在发布模式下使用优化标志编译代码(例如-O3)获得一些相关的时间。

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

  • 使用设备的有效带宽来计算内核的性能上限
  • 最小化主机和设备之间的内存传输——即使这意味着在设备上进行计算效率不高
  • 合并所有内存访问
  • 首选共享内存访问而不是全局内存访问
  • 避免在单个warp中执行代码执行分支,因为这会序列化线程

您还可以使用指令级并行性(您应该阅读这些幻灯片)。

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

附带说明一下,您还应该广泛使用错误检查,并依靠cuda-memcheck/cuda-gdb来调试您的代码。

于 2013-05-15T12:41:52.863 回答