我正在尝试计算在GPU 中计算某些内容的总时间。我正在使用cudaEventRecord和cudaEventElapsedTime来确定这一点,但我有一个意想不到的行为,或者至少对我来说意外:)我写这个例子来了解发生了什么,我仍然感到困惑。
在下面的示例中,我希望报告三次迭代的相同时间,但结果是:
2.80342
1003
2005.6
这意味着考虑CPU睡眠时间的总时间。
我做错了吗?如果没有,是否可以做我想做的事情?
#include <iostream>
#include <thread>
#include <chrono>
#include <cuda.h>
#include <cuda_runtime.h>
#include "device_launch_parameters.h"
__global__ void kernel_test(int *a, int N) {
for(int i=threadIdx.x;i<N;i+=N) {
if(i<N)
a[i] = 1;
}
}
int main(int argc, char ** argv) {
cudaEvent_t start[3], stop[3];
for(int i=0;i<3;i++) {
cudaEventCreate(&start[i]);
cudaEventCreate(&stop[i]);
}
cudaStream_t stream;
cudaStreamCreate(&stream);
const int N = 1024 * 1024;
int *h_a = (int*)malloc(N * sizeof(int));
int *a = 0;
cudaMalloc((void**)&a, N * sizeof(int));
for(int i=0;i<3;i++) {
cudaEventRecord(start[i], stream);
cudaMemcpyAsync(a, h_a, N * sizeof(int), cudaMemcpyHostToDevice, stream);
kernel_test<<<1, 1024, 0, stream>>>(a, N);
cudaMemcpyAsync(h_a, a, N*sizeof(int), cudaMemcpyDeviceToHost, stream);
cudaEventRecord(stop[i], stream);
std::this_thread::sleep_for (std::chrono::seconds(i));
cudaEventSynchronize(stop[i]);
float milliseconds = 0;
cudaEventElapsedTime(&milliseconds, start[i], stop[i]);
std::cout<<milliseconds<<std::endl;
}
return 0;
}
我附加了nsight结果以验证我的示例的行为。
Windows 8.1
Geforce GTX 780 Ti
Nvidia车手:358.50
编辑:
添加了完整的代码
附加了result
添加了SO和驱动程序信息
答案 0 :(得分:1)
如果您使用WDDM在Windows上运行程序(与使用Tesla卡或Linux的TCC相比),可能会出现问题:
WDDM内核在调用后不会立即执行,而是排入命令缓冲区。一旦缓冲区已满,它就会被刷新,并且实际执行了排队的命令。强制命令缓冲区被显式刷新的另一个选项是同步。 现在发生的事情是你在之前命令缓冲区被实际刷新...
修改强>
另请参阅https://devtalk.nvidia.com/default/topic/548639/is-wddm-causing-this-/了解问题以及cudaEventQuery(0)
如何提供帮助