我希望分析在内核上花费的总时间,运行多次,并且想知道这段代码是否会给我流式内核的总花费,或者是否需要将返回的时间乘以启动次数。
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);
答案 0 :(得分:0)
它不会为循环的所有传递捕获内核的总执行时间。
如果先前已在事件上调用cudaEventRecord(),则此调用将覆盖事件中的任何现有状态。检查事件状态的任何后续调用只会检查最近对cudaEventRecord()的调用是否完成。
如果您认为每次通过循环的执行时间大致相同,那么您可以将结果乘以传递次数。
请注意,在致电stop
cudaEventElapsedTime()
事件上发出cudaEventSynchronize()来电
答案 1 :(得分:0)
基于事件的时序被添加到CUDA以实现片上执行的细粒度时序(例如,即使事件启动/停止调用仅包含一个内核调用,您也应该获得准确的时间)。但是流和乱序执行会使cudaEventRecord()
记录的“时间戳”的含义模糊不清。 cudaEventRecord()
采用流参数,据我所知它尊重该流参数;但是流的执行可能会受到其他流的影响,例如:如果他们争夺某种资源。
因此,最佳做法是在NULL流上调用cudaEventRecord()
进行序列化。
有趣的是,英特尔与RDTSC有着相似的历史,他们在同一产品中引入了超标量执行和时间戳记录。 (对于NVIDIA,它是CUDA 1.1;对于Intel,它是奔腾。)同样,英特尔不得不修改他们对依赖RDTSC作为序列化指令的开发人员的指导,告诉他们明确序列化以获得有意义的计时结果。 / p>