2015-06-25 3 views
1

Выполняя некоторые базовые примеры CUDA, сделанные NVIDIA, я скопировал некоторый код, чтобы протестировать ускорение с CPU на вычисления GPU для матричного умножения.cudaEventRecord() Неправильно верен код процессора Visual Studio

После 30 минут просмотра результатов и просмотра моего процессора (да CPU), выполняющего вычисления в 1000 раз быстрее, чем мой GPU, я понял, что время не работает правильно. Отрезала кода выглядит (это код от NVIDIA):

//Create timers 
cudaEvent_t start; 
cudaEvent_t stop; 
float simpleKernelTime; 
float optimisedKernelTime; 

//start timer 
cudaEventCreate(&start); 
cudaEventCreate(&stop); 
cudaEventRecord(start, 0); 

matrixMultKernel<<<grid, block >>>(a_d, b_d, c_d, N); 

cudaEventRecord(stop, 0); 
cudaEventSynchronize(stop); 
cudaEventElapsedTime(&elapsedTime, start, stop); 

// Print time and do other things 

cudaEventRecord(start, 0); 

matrixMultCPU(a_h, b_h, d_, N); 

cudaEventRecord(stop, 0) 
cudaEventSynchronize(stop); 
cudaEventElapsedTime(&elapsedTime, start, stop); 

// Print time 

Этот код прекрасно работает на машине Linux (я скопировал один и тот же код, что и человек рядом со мной, и он получал хорошие сроки), но на машине с Windows 8 с Visual Studio 2013 время на процессорной части (вторая половина отрезки) не работало (всегда давало ~ 0,003 мс).

Почему это происходит? Я исправил его с помощью <time.h> (удаление cudaEventRecord() звонков и использование стандартных подходов синхронизации кода C), поэтому я не хочу знать, как это исправить, но еще больше, почему это происходит.

+0

"Я установил его с помощью' '" Что ...? Вы говорите, что время неверно, без этого, и исправить это? –

+0

@buttifulbuttefly nononono, я удалил вызовы cudaEventRecord и использовал стандартное время C. –

+1

О закрытом голосовании: «Этот код * работает *, и я знаю, как заставить его работать должным образом. Я не прошу помощи по отладке кода, это хороший теоретический вопрос, который я считаю. –

ответ

2

Из того, что я понимаю, события CUDA не предназначены для измерения времени только для процессора (только для хоста), а скорее для выполнения ядра и вызовов API CUDA. Из CUDA C Programming Guide3.2.5.6.События (курсив мой):

Среда также предоставляет возможность внимательно следить за устройства прогресс, а также выполнять точные сроки, с помощью позволяя приложение асинхронно записывать события в любую точку в программе и запрос, когда эти события будут завершены.

Я также удивлён, что вы получите в любое время (запуски ядра асинхронно), так как ваш код отсутствует cudaEventSynchronize():

cudaEventRecord(stop, 0); 
cudaEventSynchronize(stop); 
cudaEventElapsedTime(&elapsedTime, start, stop); 

Смотрите также How to Implement Performance Metrics in CUDA C/C++.

Для измерения времени только для CPU см. this thread.

EDIT:

Чтобы получить правильное время для matrixMultCPU() вам нужно добавить синхронизацию для start события:

cudaEventRecord(start, 0); 
cudaEventSynchronize(start); 
+0

Opps, мой ошибка!Я использую 'cudaEventSynchronize (stop);' в моем исходном коде. Однако 'cudaEventRecord()' работает на CPU в других системах/компиляторах (не уверен, почему). Я имею в виду, что код написан NVIDIA, а не я, и я видел, как правильно время в других ОС/компиляторах, просто не работает в моей системе. –

+0

Возможно, мой вопрос был бы сформулирован в противоположном направлении: почему 'cudaEventRecord()' работает для синхронизации времени без GPU в Linux с помощью 'nvcc'? –

+0

@AnderBiguri: Я отредактировал свой ответ. Посмотрите, работает ли это для вас. Вероятно, реализация GNU/Linux синхронизирует «запуск» неявно. –

Смежные вопросы