#timer #cuda
#таймер #cuda
Вопрос:
Я немного смущен использованием cudaEvent_t
. В настоящее время я использую clock()
вызов, подобный этому, чтобы определить продолжительность вызова ядра:
cudaThreadSynchronize();
clock_t begin = clock();
fooKernel<<< x, y >>>( z, w );
cudaThreadSynchronize();
clock_t end = clock();
// Print time difference: ( end - begin )
Я рассматриваю возможность использования таймера с более высоким разрешением cudaEvent_t
. Нужно ли мне вызывать, cudaThreadSynchronize()
прежде чем я запишу время использования cudaEventRecord()
, или это излишне?
Причина, по которой я спрашиваю, заключается в том, что есть другой вызов cudaEventSynchronize()
, который, похоже, ожидает, пока событие не будет записано. Если запись задерживается, не будет ли вычисляемая разница во времени показывать некоторое дополнительное время после завершения выполнения ядром?
Ответ №1:
На самом деле существует еще больше функций синхронизации ( cudaStreamSynchronize
). В руководстве по программированию есть подробное описание того, что делает каждый из них. Использование событий в качестве таймеров в основном сводится к этому:
//create events
cudaEvent_t event1, event2;
cudaEventCreate(amp;event1);
cudaEventCreate(amp;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(amp;dt_ms, event1, event2);
Важно синхронизировать event2
, потому что вы хотите убедиться, что все было выполнено, прежде чем вычислять время. Поскольку оба события и ядро находятся в одном потоке (порядок сохранен), event1
и kernel
также были выполнены.
Вы могли бы вызвать вместо этого cudaStreamSynchronize
or даже cudaThreadSynchronize
, но в этом случае оба варианта являются излишними.
Комментарии:
1. LumpN: Почему событие не записывается при вызове cudaEventRecord? Если он не записан при этом вызове, как он представляет время, затраченное этим ядром?
2. @Ashwin: Событие записывается, когда оно достигает вершины потока, который действует как FIFO. Когда вы вызываете cudaEventRecord, вы запускаете событие в поток. Если в потоке перед событием есть работа, событие остается необработанным в потоковом FIFO до завершения каждой операции, предшествующей ему. Все эти вызовы являются асинхронными по отношению к вызывающему потоку хоста.