Clock () time accuracy .h

I am trying to calculate the number of ticks that the function uses to run and do this using the clock() function, for example:

 unsigned long time = clock(); myfunction(); unsigned long time2 = clock() - time; printf("time elapsed : %lu",time2); 

But the problem is that the return value is a multiple of 10000, which I think is CLOCK_PER_SECOND . Is there a method or equivalent function value that is more accurate?

I use the 64-bit version of Ubuntu, but I prefer the solution to work on other systems such as Windows and Mac OS.

+7
source share
4 answers

POSIX has several more accurate timers.

  • gettimeofday() - officially obsolete, but very widely available; microsecond resolution.
  • clock_gettime() is a replacement for gettimeofday() (but not necessarily as widely available; on the old version of Solaris, -lposix4 is required for communication), with a resolution of nanoseconds.

There are other subsecond timers of greater or lesser antiquity, portability and resolution, including:

  • ftime() - resolution in milliseconds (marked as "legacy" in POSIX 2004, not in POSIX 2008).
  • clock() - which you already know about. Please note that it measures the processor time, not the elapsed time (wall clock).
  • times() - CLK_TCK or HZ . Note that this measures CPU time for parent and child processes.

Do not use ftime() or times() if there is nothing better. Final reserve, but not meeting your immediate requirements,

  • time() - resolution in one second.

The clock() function reports in units of CLOCKS_PER_SEC , which should be 1,000,000 from POSIX, but the increment may occur less frequently (100 times per second was one common frequency). The return value must be specified by CLOCKS_PER_SEC in order to get the time in seconds.

+7
source

According to the clock () man page on POSIX platforms, the value of the CLOCKS_PER_SEC macro should be 1,000,000. As you say, the return value you get from clock () is a multiple of 10,000, which means that the resolution is 10 ms.

Also note that clock () on Linux returns the approximate processor time used by the program. On Linux, the scheduler statistics are displayed again when the scheduler starts at CONFIG_HZ. Therefore, if the periodic timer is 100 Hz, you get statistics on processor time consumption with a resolution of 10 ms.

The measurements on the wall are not related to this and can be much more accurate. clock_gettime (CLOCK_MONOTONIC, ...) on a modern Linux system provides nanosecond resolution.

+1
source

The most accurate (but not highly portable) way to measure time is to count the tics of the CPU.

For example, on x86

  unsigned long long int asmx86Time () { unsigned long long int realTimeClock = 0; asm volatile ( "rdtsc\n\t" "salq $32, %%rdx\n\t" "orq %%rdx, %%rax\n\t" "movq %%rax, %0" : "=r" ( realTimeClock ) : /* no inputs */ : "%rax", "%rdx" ); return realTimeClock; } double cpuFreq () { ifstream file ( "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" ); string sFreq; if ( file ) file >> sFreq; stringstream ssFreq ( sFreq ); double freq = 0.; if ( ssFreq ) { ssFreq >> freq; freq *= 1000; } // kHz to Hz return freq; } // Timing unsigned long long int asmStart = asmx86Time (); doStuff (); unsigned long long int asmStop = asmx86Time (); float asmDuration = ( asmStop - asmStart ) / cpuFreq (); 

If you do not have x86, you will have to rewrite the assembler code according to your processor. If you need maximum accuracy, unfortunately, the only way to go ... otherwise use clock_gettime ().

+1
source

I agree with Jonathan's decision. Here is an implementation of clock_gettime () accurate to nanoseconds.

 //Import #define _XOPEN_SOURCE 500 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include <sys/time.h> int main(int argc, char *argv[]) { struct timespec ts; int ret; while(1) { ret = clock_gettime (CLOCK_MONOTONIC, &ts); if (ret) { perror ("clock_gettime"); return; } ts.tv_nsec += 20000; //goto sleep for 20000 n printf("Print before sleep tid%ld %ld\n",ts.tv_sec,ts.tv_nsec ); // printf("going to sleep tid%d\n",turn ); ret = clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME,&ts, NULL); } } 

Although it is difficult to achieve ns accuracy, it can be used to obtain accuracy in less than microseconds (700-900 ns). printf above is used to simply print stream # (it takes only 2-3 microseconds to print the statement).

-one
source

All Articles