在 Linux 中算出 nano-second 級時差
當你在需要跟時間差有高精確度的需求的時候,可能會先想到用 gettimeofday 來處理,像是這樣:
gettimeofday
1 2 3 4 5 6 7 8 9 |
#include <sys/time.h> struct timeval start, end; gettimeofday(&start, NULL); ... gettimeofday(&end, NULL); /* print diff in time */ diff(start, end); |
那如果要更高的精確度呢?例如說到 nano-seconds?
就必須要使用 clock_gettime 來處理。
就必須要使用 clock_gettime 來處理。
nano-second diff
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <time.h> static long diff_in_ns(struct timespec t1, struct timespec t2) { struct timespec diff; if (t2.tv_nsec–t1.tv_nsec < 0) { diff.tv_sec = t2.tv_sec – t1.tv_sec – 1; diff.tv_nsec = t2.tv_nsec – t1.tv_nsec + 1000000000; } else { diff.tv_sec = t2.tv_sec – t1.tv_sec; diff.tv_nsec = t2.tv_nsec – t1.tv_nsec; } return (diff.tv_sec * 1000000000.0 + diff.tv_nsec); } |
micro-second diff
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <time.h> static long diff_in_us(struct timespec t1, struct timespec t2) { struct timespec diff; if (t2.tv_nsec–t1.tv_nsec < 0) { diff.tv_sec = t2.tv_sec – t1.tv_sec – 1; diff.tv_nsec = t2.tv_nsec – t1.tv_nsec + 1000000000; } else { diff.tv_sec = t2.tv_sec – t1.tv_sec; diff.tv_nsec = t2.tv_nsec – t1.tv_nsec; } return (diff.tv_sec * 1000000.0 + diff.tv_nsec / 1000.0); } |
可以參考:man page: clock_gettime
裏面有提供 clock_gettime 可以使用的一些不同的 clock 設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
More clocks may be implemented. The interpretation of the corresponding time values and the effect on timers is unspecified. Sufficiently recent versions of glibc and the Linux kernel support the following clocks: CLOCK_REALTIME System–wide clock that measures real (i.e., wall–clock) time. Setting this clock requires appropriate privileges. This clock is affected by discontinuous jumps in the system time (e.g., if the system administrator manually changes the clock), and by the incremental adjustments performed by adjtime(3) and NTP. CLOCK_REALTIME_COARSE (since Linux 2.6.32; Linux–specific) A faster but less precise version of CLOCK_REALTIME. Use when you need very fast, but not fine–grained timestamps. Requires per–architecture support, and probably also architecture support for this flag in the vdso(7). CLOCK_MONOTONIC Clock that cannot be set and represents monotonic time since some unspecified starting point. This clock is not affected by discontinuous jumps in the system time (e.g., if the system administrator manually changes the clock), but is affected by the incremental adjustments performed by adjtime(3) and NTP. CLOCK_MONOTONIC_COARSE (since Linux 2.6.32; Linux–specific) A faster but less precise version of CLOCK_MONOTONIC. Use when you need very fast, but not fine–grained timestamps. Requires per–architecture support, and probably also architecture support for this flag in the vdso(7). CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux–specific) Similar to CLOCK_MONOTONIC, but provides access to a raw hardware–based time that is not subject to NTP adjustments or the incremental adjustments performed by adjtime(3). CLOCK_BOOTTIME (since Linux 2.6.39; Linux–specific) Identical to CLOCK_MONOTONIC, except it also includes any time that the system is suspended. This allows applications to get a suspend–aware monotonic clock without having to deal with the complications of CLOCK_REALTIME, which may have discontinuities if the time is changed using settimeofday(2). CLOCK_PROCESS_CPUTIME_ID (since Linux 2.6.12) Per–process CPU–time clock (measures CPU time consumed by all threads in the process). CLOCK_THREAD_CPUTIME_ID (since Linux 2.6.12) Thread–specific CPU–time clock. |
Leave a Reply