Timer CUDA:cudaEvent\u t和CUDAThread同步使用

Timer CUDA:cudaEvent\u t和CUDAThread同步使用,timer,cuda,Timer,Cuda,我对cudaEvent\u t的用法有点困惑。目前,我正在使用这样的clock()调用来查找内核调用的持续时间: cudaThreadSynchronize(); clock_t begin = clock(); fooKernel<<< x, y >>>( z, w ); cudaThreadSynchronize(); clock_t end = clock(); // Print time difference: ( end - begin )

我对
cudaEvent\u t
的用法有点困惑。目前,我正在使用这样的
clock()
调用来查找内核调用的持续时间:

cudaThreadSynchronize();
clock_t begin = clock();

fooKernel<<< x, y >>>( z, w );

cudaThreadSynchronize();
clock_t end = clock();

// Print time difference: ( end - begin )
cudaThreadSynchronize();
时钟开始=时钟();
(z,w);
cudaThreadSynchronize();
clock_t end=clock();
//打印时差:(结束-开始)
寻找更高分辨率的计时器,我正在考虑使用
cudaEvent\u t
。在我使用
cudaventrecord()
记下时间之前,我需要调用
cudaThreadSynchronize()
,还是它是多余的


我问这个问题的原因是因为有另一个调用
cudaEventSynchronize()
,它似乎在等待事件被记录下来。如果记录被延迟,那么计算的时差在内核完成执行后不会显示一些额外的时间吗?

实际上还有更多的同步函数(
cudaStreamSynchronize
)。《编程指南》详细描述了每一项功能。使用事件作为计时器基本上可以归结为:

//create events
cudaEvent_t event1, event2;
cudaEventCreate(&event1);
cudaEventCreate(&event2);

//record events around kernel launch
cudaEventRecord(event1, 0); //where 0 is the default stream
kernel<<<grid,block>>>(...); //also using the default stream
cudaEventRecord(event2, 0);

//synchronize
cudaEventSynchronize(event1); //optional
cudaEventSynchronize(event2); //wait for the event to be executed!

//calculate time
float dt_ms;
cudaEventElapsedTime(&dt_ms, event1, event2);
//创建事件
事件1、事件2;
cudaEventCreate(&event1);
cudaEventCreate(&event2);
//记录内核启动前后的事件
cudaEventRecord(事件1,0)//其中0是默认流
仁(…)//也使用默认流
cudaEventRecord(事件2,0);
//同步化
cudaEventSynchronize(事件1)//可选择的
cudaEventSynchronize(事件2)//等待事件执行!
//计算时间
浮动dt_-ms;
cudaeventlassedtime(&dt_ms,事件1,事件2);
event2
上进行同步非常重要,因为您希望在计算时间之前确保所有操作都已执行。由于事件和内核都在同一个流上(顺序被保留)
event1
kernel
也被执行


您可以调用
cudaStreamSynchronize
或甚至
cudaThreadSynchronize
,但在这种情况下,这两种方法都太过分了。

LumpN:为什么不在调用cudaventrecord后立即记录事件?如果在该调用中没有记录,那么它如何表示该内核所花费的时间?@Ashwin:当事件到达流的顶端时,它会被记录下来,这就像FIFO一样。当您调用cudaEventRecord时,您正在将事件推送到流中。如果在事件之前的流中有工作,则事件在流FIFO中处于未处理状态,直到它之前的每个操作完成。所有这些调用相对于调用主机线程都是异步的。