Помогите с проблемой измерения времени исполения керналов.

Такая ситуация

  1. execTime -= cutGetTimerValue( timer);
  2. //запускаю 9 керналов подряд
  3. execTime += cutGetTimerValue( timer);
  4. cutilSafeCall( cudaMemcpy( updateds, d_updateds, 1 * sizeof(int),
  5.                                         cudaMemcpyDeviceToHost) );

Получается время исполнения(значение execTime)
0.086315 мс
если же

  1. execTime -= cutGetTimerValue( timer);
  2. //запускаю 9 керналов подряд
  3. cutilSafeCall( cudaMemcpy( updateds, d_updateds, 1 * sizeof(int),
  4.                                         cudaMemcpyDeviceToHost) );
  5. execTime += cutGetTimerValue( timer);

то получается
8.067453613 мс
Как бы получается что копирование 1 элемента из глобальной памяти занимает ооооочень много времени. Однако

  1. execTime -= cutGetTimerValue( timer);
  2. //запускаю 9 керналов подряд
  3. cutilSafeCall( cudaMemcpy( updateds, d_updateds, 1 * sizeof(int),
  4.                                         cudaMemcpyDeviceToHost) );
  5. cutilSafeCall( cudaMemcpy( flags, d_flags, 12 * sizeof(int),
  6.                                         cudaMemcpyDeviceToHost) );
  7. execTime += cutGetTimerValue( timer);

execTime = 8.082438 мс
Исходя из этих данных получается что коприрование d_updateds( 1 элемент) занимает 8мс а d_flags(12 элементов) 0,015 мс
Что -то тут не так :-)

Forums: 

....Только если после запуска

....Только если после запуска кернала управление сразу не передается на Хост. Так а во время копирования хост ждет завершения предидущих керналов........

А можно как то принудительно

А можно как то принудительно указать что я хочу дождаться окончания выполнения кернала без копирования данных?

cudaSetDeviceFlags() - и

cudaSetDeviceFlags() - и ставите флаг, что хотите синхронного выполнения.

вы и дожидаетесь окончания

вы и дожидаетесь окончания выполнения кернела и только потом начинается копи данных (потому что использованы не асинхронные).
cudaThreadSynchronize() сразу после кернела будет блокировать контроль до завершения выполнения вычислений на гпу.

Не, там есть грабля. cuda*

Не, там есть грабля. cuda* API по умолчанию - асинхронное и синхронизация начинается на следующем вызове. Т.е. чтобы померять время выполнения kernel, нужно или явно синхронизироваться после него, либо выключить асинхронный режим. Без этого крышу рвет немножко :)

Что то припоминается мне по

Что то припоминается мне по поводу того что например если мемкопи стоит сразу после кернела то она выполняется только после того как завершатся вычисления.
Но вообще на беглый такой взгляд - да, асинхронно.
Вот кстати есть какой то глобальный ключ:

Programmers can globally disable asynchronous execution for all CUDA
CUDA_LAUNCH_BLOCKING
applications running on a system by setting the
environment variable to 1. This feature is provided for debugging purposes only and
should never be used as a way to make production software run reliably.

п.с. синхронизация начинается на следующем вызове
видимо сначала неправильно понял. Да, точно, о чём разговор то :)

Крышу и правдо рвало с петель

Крышу и правдо рвало с петель да несло в овраг..........
И так озвучиваю результаты опытов

Использование cudaSetDeviceFlags(cudaDeviceBlockingSync); не дало желаемого результата время запуска 9 креналов 0.086315 мс. Однако время выполенения всей программы с многочисленными вызованим керналов увеличелось с 4561 мс до 4717 мс. Хотя судя по референс мануал - это то что нужно.....

Использование принудительной синхронизациии после керналов cudaThreadSynchronize() дало положительный результат 8.079 мс. При том же вермени исполнения всей программы осталось равным 4580 мс

Совместное использование чуть повлияло на измерение керналов 8.183 мс и время выполнения программы 4727 мс

Итого замера времени исполненния я остнавился на таком варианте

  1. execTime -= cutGetTimerValue( timer);
  2. //запускаю 9 керналов подряд
  3. cudaThreadSynchronize();
  4. execTime += cutGetTimerValue( timer);
  5. cutilSafeCall( cudaMemcpy( updateds, d_updateds, 1 * sizeof(int),
  6.                                         cudaMemcpyDeviceToHost) );

ПС Для меня остался открытым вопрос что делает cudaSetDeviceFlags(cudaDeviceBlockingSync)????