cudaEventElapsedTime不是预期的行为

时间:2015-10-14 16:12:12

标签: cuda gpu

我正在尝试计算在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和驱动程序信息

  • Start eventend eventtime between

1 个答案:

答案 0 :(得分:1)

如果您使用WDDM在Windows上运行程序(与使用Tesla卡或Linux的TCC相比),可能会出现问题:

WDDM内核在调用后不会立即执行,而是排入命令缓冲区。一旦缓冲区已满,它就会被刷新,并且实际执行了排队的命令。强制命令缓冲区被显式刷新的另一个选项是同步。 现在发生的事情是你在之前命令缓冲区被实际刷新...

修改 另请参阅https://devtalk.nvidia.com/default/topic/548639/is-wddm-causing-this-/了解问题以及cudaEventQuery(0)如何提供帮助