Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

请教误差范围 #7

Open
xdaniel9 opened this issue Jun 15, 2021 · 7 comments
Open

请教误差范围 #7

xdaniel9 opened this issue Jun 15, 2021 · 7 comments

Comments

@xdaniel9
Copy link

xdaniel9 commented Jun 15, 2021

在我的服务器上,无论是程序自己calibrate还是cheat,误差都会在一分钟之内增大到微秒级甚至毫秒级
cpu是双路志强8255C,是支持constant_tsc的

另外在家里的电脑8700K上测试结果也是一样,系统都是Ubuntu 20.04.1 LTS

这里的误差是 rdtsc -> clock_gettime -> rdtsc,然后两次rdtsc结果平均值和clock_gettime结果的差

@ktprime
Copy link

ktprime commented Jul 4, 2021

多路上面可能不准,通常情况下要定期校验,
多线程情况下周期性调用init 是否有问题?

include <bits/stdc++.h> 在macOS clang++上无法编译,似乎已经不是c++标准头文件了(gcc 保留)

@MengRao
Copy link
Owner

MengRao commented Jul 4, 2021

可以周期性重复调用calibrate(),这是多线程安全的

@MengRao
Copy link
Owner

MengRao commented Jul 4, 2021

我修改了下test.cc,去掉了<bits/stdc++.h>,并去掉了sleep1秒的注释,这样可以大大提高精度降低误差

@ktprime
Copy link

ktprime commented Jul 5, 2021

服务器跨平台使用修改rdsysns,使用steady_clock 是否比high_resolution_clock 更稳定 还是没太大区别?

改成steady_clock 后,测试数据不一样,b2c 数据误差持续变大
a: 14642789863999881, b: 14642789864006251, c: 14642789864006229, a2b: 6370, b2c: -22, good: 0, rdsysns_latency: 6339
a: 14642790864015103, b: 14642790864021136, c: 14642790864021107, a2b: 6033, b2c: -29, good: 0, rdsysns_latency: 5995
a: 14642791864033885, b: 14642791864034313, c: 14642791864034287, a2b: 428, b2c: -26, good: 0, rdsysns_latency: 393
a: 14642792864040781, b: 14642792864041466, c: 14642792864041427, a2b: 685, b2c: -39, good: 0, rdsysns_latency: 637
...
a: 14643039691289192, b: 14643039691290108, c: 14643039691289648, a2b: 916, b2c: -460, good: 0, rdsysns_latency: 447
a: 14643040691297430, b: 14643040691298408, c: 14643040691297938, a2b: 978, b2c: -470, good: 0, rdsysns_latency: 499

定期同步校验init()每次至少10ms等待, 对于服务器有点卡

@ktprime
Copy link

ktprime commented Jul 5, 2021

下面这段代码每200ms运行一次,为减少同步卡顿,做了如下校验不知是否有问题

void Clock::AdjustTime() const
{
    const auto nowns = tn.rdns();
    const auto nowss = tn.rdsysns(); //steady clock
    if (std::abs(nowns - nowss) > 1000)
       tn.init();
}
  1. 调整后的时钟是否因为较准往前回拨?
  2. ns_offset 变量(不同线程读写不会有同步问题?)

@MengRao
Copy link
Owner

MengRao commented Jul 5, 2021

只需要init一次,可以重复calibrate,这样不用等10ms,也不会有多线程问题

@ktprime
Copy link

ktprime commented Jul 14, 2021

笔记本上使用发现时间漂移比较严重,盒盖再翻盖后时钟误差巨大,甚至出现回拨现象,按如下解决

void Clock::AdjustTime() const
{
    const auto nowns = tn.rdns();
    const auto nowss = tn.rdsysns(); //steady clock
    if (std::abs(nowns - nowss) > 10'000) //误差比较大,频率可能发生较大变化
       tn.init();
    else if (std::abs(nowns - nowss) > 1000) //小范围内对齐
       tn.calibrate();

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants