使用clock计算时间给出的值为零 - linux

时间:2012-04-30 05:12:57

标签: c++ c linux time cuda

我有一个cuda代码,可以在GPU上执行计算。 我正在使用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 我检查了打印开始和结束时间。 Start有一些值,但结束时间总是为零。

知道可能是什么原因?任何衡量时间的替代方案。

任何帮助将不胜感激。

由于

4 个答案:

答案 0 :(得分:7)

这里有两个问题:

  1. clock()功能的分辨率太低,无法衡量您尝试计时的事件的持续时间
  2. CUDA内核启动是一个异步操作,因此它几乎不消耗任何时间(在理智的平台上通常为10-20微秒)。除非您使用同步CUDA API调用来强制主机CPU阻塞,直到内核完成运行,否则您将不会测量执行时间。
  3. 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);
    }
    

答案 1 :(得分:5)

不要使用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);
}

答案 2 :(得分:0)

我相信您应该使用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计时,如果这是你需要的。我按照你问题的方式来定位系统。

答案 3 :(得分:0)

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