cudaEventRecord() 在 Visual Studio CPU 代码上没有正确计时

cudaEventRecord() Does not time correctly on Visual Studio CPU code

在做 NVIDIA 制作的 CUDA 的一些基本示例时,我复制了一些代码来测试从 CPU 到 GPU 计算矩阵乘法的加速。

30 分钟后查看结果并看到我的 CPU(是的 CPU)执行的计算速度比我的 GPU 快 1000 倍,我意识到计时不正确。一段代码看起来像(这是来自 NVIDIA 的代码):

//Create timers
cudaEvent_t start;
cudaEvent_t stop;
float simpleKernelTime;
float optimisedKernelTime;

//start timer
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start, 0);

matrixMultKernel<<<grid, block >>>(a_d, b_d, c_d, N);

cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&elapsedTime, start, stop);

// Print time and do other things

cudaEventRecord(start, 0);

matrixMultCPU(a_h, b_h, d_, N);

cudaEventRecord(stop, 0)
cudaEventSynchronize(stop);
cudaEventElapsedTime(&elapsedTime, start, stop);

// Print time

此代码在 Linux 机器上运行良好(我复制了与我旁边的人相同的代码,他得到了很好的时机)但在 Windows 8 机器上 Visual Studio 2013 年,CPU 部分(截断的后半部分)的时间不工作(总是给出 ~0.003ms)。

为什么会这样? 我使用 <time.h> 修复了它(删除 cudaEventRecord() 调用并使用标准 C 代码计时方法),所以我不我不想知道如何修复它,但更多的是为什么会这样。

据我了解,CUDA 事件本身并非旨在测量 CPU-仅(仅限主机)时间,而是内核执行和 CUDA API 调用。来自 CUDA C Programming Guide 3.2.5.6. Events(强调我的):

The runtime also provides a way to closely monitor the device's progress, as well as perform accurate timing, by letting the application asynchronously record events at any point in the program and query when these events are completed.

我也很惊讶你有时间(内核启动是异步的),因为你的代码丢失了 cudaEventSynchronize():

cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&elapsedTime, start, stop);

另见 How to Implement Performance Metrics in CUDA C/C++

对于 CPU-仅时间测量,请参阅 this thread

编辑:

要获得 matrixMultCPU() 的正确时间,您需要为 start 事件添加同步:

cudaEventRecord(start, 0);
cudaEventSynchronize(start);