9

I am looking for a fast way to get the elapsed time between two calls of a function in C.

I considered using jiffies, but they are not available in userland. So, should I use getimeofday() or is there any fastest way to do this.

I am only interested in the elasped time between two calls, to use in a benchmark tool.

7 Answers7

9

Take a look at clock_gettime, which provides access to high-resolution timers.

Martin B
  • 23,670
  • 6
  • 53
  • 72
  • 1
    clock_gettime() with the CLOCK_MONOTONIC source is preferred to do relative timing. gettimeofday() is prone to error if a user or process can change the current time. – KFro Sep 06 '09 at 02:44
9

I'd get the processor time via clock() from time.h. To get useful values, convert to milliseconds via CLOCKS_PER_SEC:

clock_t start = clock();
// [...]
clock_t end = clock();
unsigned long millis = (end - start) * 1000 / CLOCKS_PER_SEC;
Christoph
  • 164,997
  • 36
  • 182
  • 240
  • 1
    clock() time seems not equal to real time. http://stackoverflow.com/questions/556405/what-do-real-user-and-sys-mean-in-the-output-of-time1 – xhan Aug 17 '12 at 10:56
  • after tested the clock() time return the system+user time but not the real time. use gettimeofday instead – xhan Aug 17 '12 at 11:08
  • @xhan: depends on your use case - for a benchmarking tool, processor time is probably a better metric than wallclock time – Christoph Aug 17 '12 at 11:16
3

Yes, gettimeofday() would suffice if you want to find the actual elapsed. If you need to find the CPU time, then you can use clock(). In many cases, both approach would give similar result (unless there is a sleep or some sort of wait in code). An example of clock() can be found here:
http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_19.html

swatkat
  • 4,785
  • 1
  • 23
  • 17
2

If you're on an x86/x64 architecture, and you're running on a single CPU, you might consider reading the time-stamp counter on the CPU to get a cycle-count. Wikipedia has more information. Note that this approach is less useful if your application is running on multiple CPUs, since each CPU will have its own TSC. Also be wary of frequency scaling if you decide that you want to convert cycles -> time units.

andri
  • 11,171
  • 2
  • 38
  • 49
1

If your kernel supports gettimeofday() as a vsyscall (virtual system call), then using this will be faster than calling a regular system call such as clock(). See Andrea Arcangeli's presentation for some information on how vsyscalls work.

mark4o
  • 58,919
  • 18
  • 87
  • 102
0

Bit of a late addition, however the time uility available on any linux/unix may be a lighter weight way of achieving what you want. Here are 2 examples

time ls -l stuff*
ls: stuff*: No such file or directory
    0.01s real     0.00s user     0.00s system


 time -c run_script.csh` 

...

real    1m22.38s
user    0m14.67s
sys     0m1.06s
Wiretap
  • 771
  • 2
  • 9
  • 13
0

The following works for me on CentOS 6:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#if ! defined(_POSIX_C_SOURCE)
#  error "_POSIX_C_SOURCE undefined"
#endif

#if _POSIX_C_SOURCE < 199309L
#  error "_POSIX_C_SOURCE < 199309L"
#endif

int main(int, char**){
  struct timespec start, stop;
  struct timespec stop;
  if(clock_gettime(CLOCK_MONOTONIC, &start )) goto err_out;
  if(clock_gettime(CLOCK_MONOTONIC, &stop  )) goto err_out;
  printf("start == {tv_sec: %d, tv_nsec: %d}\n", start.tv_sec, start.tv_nsec);
  printf("stop  == {tv_sec: %d, tv_nsec: %d}\n", stop.tv_sec,  stop.tv_nsec );
  printf("stop.tv_nsec - start.tv_nsec == %d\n", stop.tv_nsec - start.tv_nsec);
  return EXIT_SUCCESS;
 err_out:
  perror("clock_gettime");
  return EXIT_FAILURE ;
}

...although it does require librt:

$ make dur
cc     dur.c   -o dur
/tmp/cc1yF58x.o: In function `main':
dur.c:(.text+0x1c): undefined reference to `clock_gettime'
dur.c:(.text+0x4e): undefined reference to `clock_gettime'
collect2: ld returned 1 exit status
make: *** [dur] Error 1
$ LDFLAGS="-lrt" make dur
cc   -lrt  dur.c   -o dur
$ ./dur
start == {tv_sec: 206247, tv_nsec: 411717209}
stop  == {tv_sec: 206247, tv_nsec: 411759791}
stop.tv_nsec - start.tv_nsec == 42582
rubicks
  • 4,912
  • 1
  • 30
  • 41