[英]Is time() from time.h monotonic?
我說的是老式的 time() 函數,它以 UTC 時間返回自紀元以來的秒數。 這應該是單調的,對吧?
在我的測試中(見下文),它的運行速度比使用 CLOCK_MONOTONIC 的 clock_gettime 快大約 10 倍,所以我想知道它是否可以用作單調定時器,用於我需要低延遲低分辨率單調定時器的情況。 (例如,斷開服務器上存在時間超過 15 秒的連接)
這是代碼,以防您好奇:
#include <cstdio>
#include <chrono>
#include <time.h>
#include <sys/time.h>
#include <x86intrin.h>
using namespace std;
class Timer {
std::chrono::time_point<std::chrono::steady_clock> start;
public:
inline double t() {
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> diff = end - start;
return diff.count();
}
inline double milli() { return t() * 1000.0;}
Timer() :start(std::chrono::steady_clock::now()) {}
};
const int nloop = 10000000;
void cpp_steady() {
for (int i=0;i<nloop;i++) {
chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
}
}
void get_tod() {
timeval tv;
for (int i=0;i<nloop;i++) {
gettimeofday(&tv, 0);
}
}
void get_clock() {
for (int i=0;i<nloop;i++) {
clock_t t = clock();
}
}
void get_time() {
int x =0;
for (int i=0;i<nloop;i++) {
time_t t = time(0);
x+=t*3;
}
fprintf(stderr,"%d\n",x);
}
void get_clock_gettime() {
timespec ts;
for (int i=0;i<nloop;i++) {
clock_gettime(CLOCK_MONOTONIC, &ts);
}
}
void get_rdtsc() {
for (int i=0;i<nloop;i++) {
__rdtsc();
}
}
void emptyloop() {
int x=0;
for (int i=0;i<nloop;i++) {
x+=3*i;
}
fprintf(stderr,"%d\n",x);
}
void measure(const char *name, void (*f)()) {
Timer t;
f();
double dur = t.milli();
printf(" %-15s : %.3f ms\n", name, dur);
}
int main () {
measure("cpp_steady", cpp_steady);
measure("gettimeofday", get_tod);
//measure("clock", get_clock); //too fking slow
measure("time", get_time);
measure("clock_gettime", get_clock_gettime);
measure("rdtsc", get_rdtsc);
measure("empty", emptyloop);
return 0;
}
這是輸出:
./clk_bench 2>/dev/null
cpp_steady : 212.415 ms
gettimeofday : 200.733 ms
time : 19.526 ms
clock_gettime : 197.791 ms
rdtsc : 75.169 ms
empty : 2.821 ms
(順便說一句,我知道這只是幾納秒的問題,並不重要,但實際上 time_t 也消耗更少的內存並且比替代方案更便攜......)
除了不能保證time
是單調的之外,沒有明確的答案。
它只是返回內核認為當前時間是什么。 如果有保證時鍾永遠不會倒退的操作程序,如果遵守這些程序,那么它應該是單調的。 例如,在使用ntpd
進行時間同步的 Unix 機器上,時鍾不應倒退。 但是,如果管理員(在機器上具有管理員權限的人)發現機器時間不准確並將其向后修復,那么任何單調假設都將是錯誤的。
從std::time()
返回的值的編碼未指定。 然而,在大多數實現中,它返回自 unix 紀元以來的當前牆壁時間(以秒為單位)。
如果您的掛鍾是單調的,那么std::time()
也將是單調的。 然而,掛鍾通常不能保證是單調的。 許多現代 Linux 系統使用時鍾拖尾將其時鍾調整為 NTP 源,而不是向后跳,但即使在這種情況下,用戶也可以進行干預並手動向后設置時鍾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.