fast elapsed time on linux

2019-01-23 07:50发布

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.

标签: c linux time
7条回答
戒情不戒烟
2楼-- · 2019-01-23 07:56

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;
查看更多
Deceive 欺骗
3楼-- · 2019-01-23 07:59

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.

查看更多
做自己的国王
4楼-- · 2019-01-23 08:03

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.

查看更多
做个烂人
5楼-- · 2019-01-23 08:05

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
查看更多
手持菜刀,她持情操
6楼-- · 2019-01-23 08:08

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

查看更多
一纸荒年 Trace。
7楼-- · 2019-01-23 08:15

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
查看更多
登录 后发表回答