测量内核在使用流时所花费的总时间

时间:2014-02-26 17:35:46

标签: c cuda

我希望分析在内核上花费的总时间,运行多次,并且想知道这段代码是否会给我流式内核的总花费,或者是否需要将返回的时间乘以启动次数。

cudaEvent_t start, stop;    
cudaEventCreate(&start);
cudaEventCreate(&stop);


for(x=0; x<SIZE; x+=N*2){

     gpuErrchk(cudaMemcpyAsync(data_d0, data_h+x, N*sizeof(char), cudaMemcpyHostToDevice, stream0));
     gpuErrchk(cudaMemcpyAsync(data_d1, data_h+x+N, N*sizeof(char), cudaMemcpyHostToDevice, stream1));


     gpuErrchk(cudaMemcpyAsync(array_d0, array_h, wrap->size*sizeof(node_r), cudaMemcpyHostToDevice, stream0));
     gpuErrchk(cudaMemcpyAsync(array_d1, array_h, wrap->size*sizeof(node_r), cudaMemcpyHostToDevice, stream1));

     cudaEventRecord(start, 0);
        GPU<<<N/512,512,0,stream0>>>(array_d0, data_d0, out_d0 );
        GPU<<<N/512,512,0,stream1>>>(array_d1, data_d1, out_d1);
     cudaEventRecord(stop, 0);

     gpuErrchk(cudaMemcpyAsync(out_h+x, out_d0 , N * sizeof(int), cudaMemcpyDeviceToHost, stream0));
     gpuErrchk(cudaMemcpyAsync(out_h+x+N, out_d1 ,N *  sizeof(int), cudaMemcpyDeviceToHost, stream1));

} 

float elapsedTime;
cudaEventElapsedTime(&elapsedTime, start, stop);
cudaEventDestroy(start);
cudaEventDestroy(stop);
printf("Time %f ms\n", elapsedTime);

2 个答案:

答案 0 :(得分:0)

它不会为循环的所有传递捕获内核的总执行时间。

来自documentation

  

如果先前已在事件上调用cudaEventRecord(),则此调用将覆盖事件中的任何现有状态。检查事件状态的任何后续调用只会检查最近对cudaEventRecord()的调用是否完成。

如果您认为每次通过循环的执行时间大致相同,那么您可以将结果乘以传递次数。

请注意,在致电stop

之前,您应在cudaEventElapsedTime()事件上发出cudaEventSynchronize()来电

答案 1 :(得分:0)

基于事件的时序被添加到CUDA以实现片上执行的细粒度时序(例如,即使事件启动/停止调用仅包含一个内核调用,您也应该获得准确的时间)。但是流和乱序执行会使cudaEventRecord()记录的“时间戳”的含义模糊不清。 cudaEventRecord()采用流参数,据我所知它尊重该流参数;但是流的执行可能会受到其他流的影响,例如:如果他们争夺某种资源。

因此,最佳做法是在NULL流上调用cudaEventRecord()进行序列化。

有趣的是,英特尔与RDTSC有着相似的历史,他们在同一产品中引入了超标量执行和时间戳记录。 (对于NVIDIA,它是CUDA 1.1;对于Intel,它是奔腾。)同样,英特尔不得不修改他们对依赖RDTSC作为序列化指令的开发人员的指导,告诉他们明确序列化以获得有意义的计时结果。 / p>

Why isn't RDTSC a serializing instruction?