使用时钟计算时间值为零 – linux

我有一个在GPU上执行计算的cuda代码。 我正在使用clock(); 找出时机

我的代码结构是

__global__ static void sum(){ // calculates sum } extern "C" int run_kernel(int array[],int nelements){ clock_t start, end; start = clock(); //perform operation on gpu - call sum end = clock(); double elapsed_time = ((double) (end - start)) / CLOCKS_PER_SEC; printf("time required : %lf", elapsed_time); } 

但时间总是0.0000我检查打印开始和结束时间。 开始有一些价值,但结束时间总是零。

任何想法可能是什么原因? 任何替代方法来衡量时间。

任何帮助,将不胜感激。

谢谢

这里有两个问题:

  1. clock()函数的分辨率太低,无法测量您尝试使用的事件的持续时间
  2. CUDA内核启动是一个异步操作,因此它几乎不消耗时间(通常在理性平台上10-20微秒)。 除非您使用同步CUDA API调用来强制主机CPU在内核完成运行之前阻塞,否则您将不会测量执行时间。

CUDA拥有自己的高精度计时API,并且是推荐在GPU上运行的时间的推荐方式。 使用它的代码看起来像这样:

 int run_kernel(int array[],int nelements){ cudaEvent_t start,stop; cudaEventCreate(&start); cudaEventCreate(&stop); cudaEventRecord(start, 0); // //perform operation on gpu - call sum // cudaEventRecord(stop, 0); cudaEventSynchronize(stop); float elapsedTime; cudaEventElapsedTime(&elapsedTime, start, stop); printf("time required : %f", elapsed_time); cudaEventDestroy(start); cudaEventDestroy(stop); } 

不要使用clock来启动CUDA内核。 使用cudaEventElapsedTime 。 即使clock精确度足以确定内核的时间(不),内核启动也是异步的,这意味着在内核完成之前,控制流将返回到调用函数。

就是这样:

 void run_kernel(...) { // create "events" which record the start & finish of the kernel of interest cudaEvent_t start, end; cudaEventCreate(&start); cudaEventCreate(&end): // record the start of the kernel cudaEventRecord(start); // perform operation on gpu - call sum sum<<<...>>>(...); // record the end of the kernel cudaEventRecord(end); // get elapsed time. Note that this call blocks // until the kernel is complete float ms; cudaEventElapsedTime(&ms, start, end); printf("time required : %f milliseconds", ms); cudaEventDestroy(start); cudaEventDestroy(end); } 

我相信你应该使用clock_gettime()和CLOCK_MONOTONIC来衡量现在流逝的时间到高分辨率。 在我的电脑上,分辨率是1ns,足够像样。

你可以使用它

 #include <time.h> ... struct timespec start, end, res; clock_getres(CLOCK_MONOTONIC, &res); /* exact format string depends on your system, on mine time_t is long */ printf("Resolution is %ld s, %ld ns\n" res.tv_sec, res.tv_nsec); clock_gettime(CLOCK_MONOTONIC, &start); /* whatever */ clock_gettime(CLOCK_MONOTONIC, &end); 

-lrt编译

编辑:我看到,我采取了错误的做法,显然你应该使用CUDA计时,如果这是你所需要的。 我遵循你定义系统时间的问题。

cuda内核启动是异步的,所以你必须在内核之后添加cudaThreadSynchronize()。