我有一个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有一些值,但结束时间总是为零。
知道可能是什么原因?任何衡量时间的替代方案。
任何帮助将不胜感激。
由于
答案 0 :(得分:7)
这里有两个问题:
clock()
功能的分辨率太低,无法衡量您尝试计时的事件的持续时间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()。