Точность функции clock() в C
у меня есть некоторый код, который пытается определить время выполнения блока кода.
#include <time.h>
#include <stdio.h>
int main()
{
clock_t start_t, end_t, total_t;
int i;
start_t = clock(); //clock start
printf("Starting of the program, start_t = %ldn", start_t);
printf("Going to scan a big loop, start_t = %ldn", start_t);
for(i=0; i< 10000000; i++) //trying to determine execution time of this block
{
}
end_t = clock(); //clock stopped
printf("End of the big loop, end_t = %ldn", end_t);
total_t = (long int)(end_t - start_t);
printf("Total time taken by CPU: %lun", total_t );
return(0);
}
вывод фрагмента кода на моей машине -
Starting of the program, start_t = 8965
Going to scan a big loop, start_t = 8965
End of the big loop, end_t = 27259
Total time taken by CPU: 18294
поэтому, если мой процессор работал на 21 МГц и предполагал, что это было единственное, что выполнялось, каждый машинный цикл был бы приблизительно равен 47 наносекундам, поэтому (18294 * 47) = 859818 наносекунд.
будет ли это время выполнения цикла for В моем коде? Я делаю что-то неправильное? предположения здесь.
1 ответов
единица времени, используемая clock
функция является произвольным. На большинстве платформ это не связано со скоростью процессора. Это чаще всего связано с частотой внешнего прерывания таймера , которое может быть настроено в программном обеспечении , или с исторической ценностью, которая сохранялась для совместимости в течение многих лет эволюции процессора. Вам нужно использовать макрос CLOCKS_PER_SEC
для преобразования в режиме реального времени.
printf("Total time taken by CPU: %fs\n", (double)total_t / CLOCKS_PER_SEC);
стандартная библиотека C была разработана для реализации на широком ряд оборудования, включая процессоры которые не имеют внутренний таймер и полагаются на внешнем периферийном устройстве для того чтобы сказать время. Многие платформы имеют более точные способы измерения времени настенных часов, чем time
и более точные способы измерения потребления процессора, чем clock
. Например, в системах POSIX (например, Linux и других Unix-подобных системах) вы можете использовать getrusage
, который имеет точность микросекунды.
struct timeval start, end;
struct rusage usage;
getrusage(RUSAGE_SELF, &usage);
start = usage.ru_utime;
…
getrusage(RUSAGE_SELF, &usage);
end = usage.ru_utime;
printf("Total time taken by CPU: %fs\n", (double)(end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1e-6);
где имеется, clock_gettime(CLOCK_THREAD_CPUTIME_ID)
или clock_gettime(CLOCK_PROCESS_CPUTIME_ID)
может дать лучшую точность. Он имеет точность наносекунды.
обратите внимание на разницу между точностью и точностью: точность-это блок, который сообщил о значения. Точность как закрыть значений в реальные значения. Если вы не работаете над система реального времени, нет жестких гарантий относительно того, сколько времени занимает кусок кода, включая вызов самих функций измерения.
некоторые процессоры имеют часы, которые подсчитывают циклы процессора, а не время настенных часов, но это становится очень специфичным для системы.
всякий раз, делая бенчмарки, остерегайтесь того, что вы измеряете выполнение этого конкретного исполняемого файла на этом конкретном процессоре в этих конкретных обстоятельствах, и результаты могут или не могут обобщаться на другие ситуации. Например, пустой цикл в вашем вопросе будет оптимизирован большинством компиляторов, если вы не отключите оптимизацию. Измерение скорости неоптимизированного кода обычно бессмысленно. Даже если вы добавляете реальную работу в цикл, остерегайтесь игрушечных тестов: они часто не имеют тех же характеристик производительности, что и реальный код. На современных высокопроизводительных процессорах, таких как ПК и смартфоны, тесты CPU-интенсивного кода часто очень чувствительны к эффектам кэша, и результаты могут зависеть от того, что еще работает в системе, от точной модели процессора (из-за разных размеров и макетов кэша), от адреса, по которому код оказывается загруженным и т. д.