The accuracy of the clock () function in C

I have code that is trying to determine the execution time of a block of code.

#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 = %ld\n", start_t); printf("Going to scan a big loop, start_t = %ld\n", 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 = %ld\n", end_t); total_t = (long int)(end_t - start_t); printf("Total time taken by CPU: %lu\n", total_t ); return(0); } 

Outputting a snippet of code on my computer

 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 

So, if my processor worked at a frequency of 21 MHz and assuming that this is the only thing that is executed, each machine cycle will be approximately 47 nanoseconds, therefore (18294 * 47) = 859818 nanoseconds.

Will this be the for loop runtime in my code? I make some wrong assumptions here.

+7
c time clock
source share
1 answer

The unit of time used by the clock function is arbitrary. On most platforms, it is not related to processor speed. This is most often due to the frequency of the external timer interrupt, which can be configured in the software, or the historical value, which was stored for compatibility through the years of the evolution of the processor. You need to use the CLOCKS_PER_SEC macro to convert in real time.

 printf("Total time taken by CPU: %fs\n", (double)total_t / CLOCKS_PER_SEC); 

The C standard library was designed to be implemented on a wide range of hardware, including processors that do not have an internal timer and rely on external peripherals to talk about time. On many platforms, there are more accurate methods for measuring wall clock time than time , and more accurate methods for measuring CPU consumption than clock . For example, on POSIX systems (like Linux and other Unix-like systems) you can use getrusage , which has precision in microseconds.

 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); 

Where available, clock_gettime(CLOCK_THREAD_CPUTIME_ID) or clock_gettime(CLOCK_PROCESS_CPUTIME_ID) can give better accuracy. It has nanosecond accuracy.

Note the difference between accuracy and accuracy: accuracy is the unit that values ​​are reported. The accuracy is how close the values ​​are to the real values. If you are not working with the system in real time , there are no solid guarantees as to how long a part of the code takes, including calling the measurement functions themselves.

Some processors have a cyclic clock that counts the processor cycles rather than the wall clock time, but this becomes very system-specific.

Whenever you do tests, be careful that what you are measuring is running this particular executable on this particular CPU in these specific circumstances, and the results may or may not be generalized in other situations. For example, the empty loop in your question will be optimized by most compilers, unless you turn off optimization. Measuring the speed of non-optimized code is usually pointless. Even if you add real work to the cycle, beware of toy tests: they often do not have the same performance characteristics, such as real-world code. On modern high-performance CPUs, such as those found on PCs and smartphones, tests of code that uses a processor intensively are often very sensitive to cache effects, and the results may depend on what else is running on the system, on the exact processor model (due to different sizes and cache layouts), to the address to which the code is downloaded, etc.

+4
source share

All Articles