关于代码的执行时间
注意1:系统中有两个 time,一个是 bash 内置的 time 命令,一个是由 time 包提的 /usr/bin/time , 直接执行 time 命令时使用的是 bash 内置的 time。
使用 bash 中的 time 统计一个进程的执行时间如下:
$ time sleep 1
real 0m1.013s
user 0m0.001s
sys 0m0.001s
real
: 表示 wall time(挂钟时间), 底层使用gettimeofday()
API 来获取时间,它统计的是物理世界中的时间;user
: 表示 CPU user time, 底层使用getrusage()
或者times()
来获取时间,它统计的是用户态的代码消耗的 CPU 时间,如果代码没有在 CPU 上运行则不会统计在内;sys
: 和 user 类似,只不过统计程序在内核态运行的时间;
user + sys 表示这个进程(及其子进程)的代码(及其调用的代码)实际在 CPU 上运行的时间,该时间的统计依赖 CPU 硬件,大部分 CPU 硬件都提供了该功能。
系统除了提供以上 API, 还提供了其他的 API 可以用来进行性能参数收集,比如:
clock()
: 统计当前程序已经执行的 cpu clock ticks(CPU time);-
clock_gettime(type,*)
: 根据参数获取不同的时间:// file: include/bits/time.h /* Identifier for system-wide realtime clock. */ # define CLOCK_REALTIME 0 /* Monotonic system-wide clock. */ # define CLOCK_MONOTONIC 1 /* High-resolution timer from the CPU. */ # define CLOCK_PROCESS_CPUTIME_ID 2 /* Thread-specific CPU-time clock. */ # define CLOCK_THREAD_CPUTIME_ID 3 /* Monotonic system-wide clock, not adjusted for frequency scaling. */ # define CLOCK_MONOTONIC_RAW 4 /* Identifier for system-wide realtime clock, updated only on ticks. */ # define CLOCK_REALTIME_COARSE 5 /* Monotonic system-wide clock, updated only on ticks. */ # define CLOCK_MONOTONIC_COARSE 6 /* Monotonic system-wide clock that includes time spent in suspension. */ # define CLOCK_BOOTTIME 7 /* Like CLOCK_REALTIME but also wakes suspended system. */ # define CLOCK_REALTIME_ALARM 8 /* Like CLOCK_BOOTTIME but also wakes suspended system. */ # define CLOCK_BOOTTIME_ALARM 9 /* Like CLOCK_REALTIME but in International Atomic Time. */ # define CLOCK_TAI 11
如果要统计 cpu time, 则推荐使用
CLOCK_MONOTONIC
参数。C++11 中的
system_clock::now()
使用gettimeofday()
或者std::time()
,而steady_clock::now()
则使用clock_gettime(CLOCK_MONOTONIC,*)
; time()
: 获取当前的 real time,精度在某些设备上只有 1s,应该避免用于性能统计;-
getrusage()
: 获取资源使用情况;struct rusage { struct timeval ru_utime; /* user CPU time used */ struct timeval ru_stime; /* system CPU time used */ long ru_maxrss; /* maximum resident set size */ long ru_ixrss; /* integral shared memory size */ long ru_idrss; /* integral unshared data size */ long ru_isrss; /* integral unshared stack size */ long ru_minflt; /* page reclaims (soft page faults) */ long ru_majflt; /* page faults (hard page faults) */ long ru_nswap; /* swaps */ long ru_inblock; /* block input operations */ long ru_oublock; /* block output operations */ long ru_msgsnd; /* IPC messages sent */ long ru_msgrcv; /* IPC messages received */ long ru_nsignals; /* signals received */ long ru_nvcsw; /* voluntary context switches */ long ru_nivcsw; /* involuntary context switches */ };
包括 CPU time, 文件系统IO调用次数,上下文切换次数等。
参考资料:
- execute_cmd.c - bash.git - bash
- chrono.cc source code [libstdc++-v3/src/c++11/chrono.cc] - Woboq Code Browser
- unix - What do 'real', 'user' and 'sys' mean in the output of time(1)? - Stack Overflow
- clock_gettime(3): clock/time functions - Linux man page
- c++ - Easily measure elapsed time - Stack Overflow
- C: using clock() to measure time in multi-threaded programs - Stack Overflow
- getrusage(2) - Linux manual page
- clock - C++ Reference
- times(2) - Linux manual page