在做 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 机器上运行良好(我复制了与我旁边的人相同的代码,他的时间安排得很好)但在装有 Visual Studio 2013 的 Windows 8 机器上,CPU 部分的时间(下半部分)剪断的)不工作(总是给出 ~0.003ms)。
为什么会这样? 我使用 <time.h>
修复了它(删除 cudaEventRecord()
调用并使用标准 C 代码计时方法),所以我不想知道如何修复它,但更多的是为什么会发生这种情况。
最佳答案
据我了解,CUDA 事件本身并非旨在测量仅 CPU(仅主机)时间,而是内核执行和 CUDA API 调用。来自CUDA C Programming Guide 3.2.5.6.
事件(强调我的):
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);
关于cudaEventRecord() 在 Visual Studio CPU 代码上计时不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31046158/