По сути, то, что вы измеряете, поскольку время вашего процессора - это время, которое требуется для
- записать первое событие,
- настроить запуск ядра с соответствующими параметрами,
- отправьте необходимые команды в графический процессор,
- запустить ядро на GPU,
- запустить ядро на GPU,
- дождаться уведомления о том, что выполнение графического процессора завершено, чтобы вернуться к ЦПУ, и
- записать второе событие.
Также обратите внимание, что ваш метод измерения времени ЦП измеряет не только время обработки, затраченное вашим процессом / потоком, а скорее общее системное время (которое потенциально включает время обработки, потраченное другими процессами / потоками, пока ваш процесс / поток не обязательно был даже запущен). Я должен признать, что даже в свете всего этого время процессора, о котором вы сообщаете, по-прежнему намного больше, чем время GPU, чем я обычно ожидаю. Но я не уверен, что это действительно весь твой код. На самом деле, я скорее сомневаюсь в этом, учитывая, что, например, printf()
на самом деле ничего не печатает. Таким образом, могут быть некоторые дополнительные факторы, о которых мы не знаем, но которые все же необходимо учитывать, чтобы полностью объяснить ваше время.
В любом случае, скорее всего, ни одно из двух измерений, которые вы проводите, на самом деле не измеряет то, что вы действительно хотели измерить. Если вас интересует время, необходимое для запуска ядра, используйте события CUDA. Однако, если вы сначала синхронизируете и только потом записываете событие окончания, время между событиями начала и конца будет временем между началом выполнения ядра, процессором, ожидающим завершения выполнения ядра, и тем временем, которое может потребоваться для запишите второе событие и пусть оно попадет в GPU, чтобы вы могли спросить GPU, в какое время оно было получено. Думайте о событиях как о маркерах, которые отмечают определенную точку в потоке команд, отправляемом в графический процессор Скорее всего, вы действительно хотели написать это:
cudaEventRecord(startGPU, stream); // mark start of kernel execution
Kernel<<<abc, xyz, stream>>>();
cudaEventRecord(stopGPU, stream); // mark end of kernel execution
cudaEventSynchronize(stopGPU); // wait for results to be available
и затем используйте cudaEventElapsedTime()
, чтобы получить время между двумя событиями.
Также обратите внимание, что gettimeofday()
является необязательно надежным способом получения времени с высоким разрешением. В C ++ вы можете использовать, например, std::steady_clock
или std::high_resolution_clock
(я бы прибегнул к последнему, только если этого нельзя избежать, так как это не гарантируется и убедитесь, что период времени действительно достаточен для того, что вы пытаетесь измерить).