У меня возникли проблемы с пониманием вызова синхронизации CUDA. Исходя из моего личного понимания вывода nvprof
, среда выполнения наших программ для GPU состоит из двух частей: время работы ядра GPU и время выполнения API CUDA , и у нас есть
Total Runtime = GPU Kernel Runtime + CUDA API Runtime
Однако представьте, что у нас большое ядро A
и маленькое ядро B
. Очевидно, что время ядра GPU A
будет больше B
. Но как насчет времени для звонков cudaDeviceSynchronize
? Всегда ли гарантируется, что A
будет тратить больше времени на синхронизацию по сравнению с B
? Какие факторы определяют продолжительность звонков cudaDeviceSynchronize
?
Извините, но просто хочу уточнить мой вопрос: предположим, что у нас есть следующая программа:
float * a, b, c; time_T tic, toc, t_A, t_B;
tic = time();
kernel_A <<< ... >>> (a, b, c);
cudaDeviceSynchronize();
toc = time(); t_A = toc - tic;
tic = time()
kernel_B <<< ... >>> (a, b, c);
cudaDeviceSynchronize();
toc = time(); t_B = toc - tic;
Предположим, что kernel_B
выполняет поэлементное вычисление c = a + b
, а kernel_A
делает то же самое, за исключением 10
итераций.
Очевидно, с нашей точки зрения, kernel_A
должно занять большее время для выполнения по сравнению с kernel_B
(т.е. t_A > t_B
). Проблема в том, почему выполнение kernel_A
?
занимает больше времени
В соответствии с формулой времени выполнения, заданной nvprof
, которая гласит, что Total Runtime = GPU Kernel Runtime + CUDA API Runtime
, есть три возможных объяснения:
kernel_A
имеет больше GPU Kernel Runtime
.
kernel_A
имеет больше CUDA API Runtime
(т.е. cudaDeviceSynchronize
).
kernel_A
длиннее в обоих компонентах.