tscns icon indicating copy to clipboard operation
tscns copied to clipboard

请教为什么从rdtscp改回了rdtsc

Open a5066987 opened this issue 1 year ago • 16 comments

我没理解错的话rdtsc不是应该需要加一个lfence或者mfence吗

a5066987 avatar Jul 07 '22 06:07 a5066987

rdtsc的准确性已经足够了。而rdtscp有些较老的cpu不支持,而且延迟比rdtsc高1ns

MengRao avatar Jul 07 '22 09:07 MengRao

目前测试看新旧版本性能差不多

ktprime avatar Jul 07 '22 09:07 ktprime

测试发现时间变小, win和WSL-linux 都存在。 定期会调用calibrate()

ktprime avatar Jul 11 '22 07:07 ktprime

时间变小是指什么呢

MengRao avatar Jul 11 '22 07:07 MengRao

时间变小是指什么呢

t1 = tn.rdns(); ...运行大概不到10分钟 t2 = tn.rdns(); t2 < t1

ktprime avatar Jul 11 '22 07:07 ktprime

有tscns_test的输出吗?

MengRao avatar Jul 11 '22 07:07 MengRao

我试试debug 看看

ktprime avatar Jul 11 '22 07:07 ktprime

  void saveParam(int64_t base_tsc, int64_t base_ns, int64_t sys_ns, double new_ns_per_tsc) {
    last_ns = sys_ns;
    last_ns_err = base_ns - sys_ns;
    printf("  base_tsc = %lld, base_ns = %lld, diff = %d ns, new_ns_per_tsc = %.4lf\n",
        base_tsc, base_ns, (int)last_ns_err, new_ns_per_tsc);
    assert(new_ns_per_tsc > 0); /**/ crash here**

base_tsc = 756851268448631, base_ns = 1657526685132171397, diff = -2147483648 ns, new_ns_per_tsc = -0.5706

等你修复 退回版本1了。 如果calibrate 间隔超过30s 会有问题?

ktprime avatar Jul 11 '22 08:07 ktprime

diff = -2147483648 ns, 偏离了两秒钟了不太正常。可以run一下tscns_test程序,把前几秒的输出发一下吗,谢谢!

MengRao avatar Jul 11 '22 08:07 MengRao

wsl2 init tsc_ghz: 3.00001659966801 rdsys_latency: 87.3126873126873, rdtsc_latency: 5.71268731268731, rdns_latency: 6.01268731268731, tmp: -5355641559474113368 calibrate_latency: 5, tsc_ghz: 3.00001659966801, b2c: 336, c2d: 17, err: 0, rdsysns_latency: 347 calibrate_latency: 9, tsc_ghz: 3.00001659966801, b2c: 4591, c2d: -2509, err: -2509, rdsysns_latency: 2076 calibrate_latency: 10, tsc_ghz: 3.00001659966801, b2c: 7298, c2d: -5206, err: -5206, rdsysns_latency: 2086 calibrate_latency: 9, tsc_ghz: 3.00001659966801, b2c: 10065, c2d: -8030, err: -8030, rdsysns_latency: 2029 calibrate_latency: 9, tsc_ghz: 3.00001659966801, b2c: 13125, c2d: -10793, err: -10793, rdsysns_latency: 2326 calibrate_latency: 8, tsc_ghz: 3.00001659966801, b2c: 15494, c2d: -13563, err: -13563, rdsysns_latency: 1925 calibrate_latency: 1958, tsc_ghz: 2.9999833228703, b2c: 16742, c2d: -16597, err: -16597, rdsysns_latency: 139 calibrate_latency: 8, tsc_ghz: 2.9999833228703, b2c: 15497, c2d: -13528, err: -13528, rdsysns_latency: 1963 calibrate_latency: 9, tsc_ghz: 2.9999833228703, b2c: 12767, c2d: -10734, err: -10734, rdsysns_latency: 2027 calibrate_latency: 5, tsc_ghz: 2.9999833228703, b2c: 9785, c2d: -7981, err: -7981, rdsysns_latency: 1798 calibrate_latency: 9, tsc_ghz: 2.9999833228703, b2c: 7345, c2d: -5227, err: -5227, rdsysns_latency: 2112 calibrate_latency: 7, tsc_ghz: 2.9999833228703, b2c: 4341, c2d: -2455, err: -2455, rdsysns_latency: 1880

ktprime avatar Jul 11 '22 08:07 ktprime

看上去挺正常的,你在自己程序中init()有填参数吗?另外,是一个线程调用calibrate()的吗?

MengRao avatar Jul 11 '22 09:07 MengRao

init 默认参数,单线程程序。30秒调用一次 calibrate() 如果改成1秒调用一次就OK

ktprime avatar Jul 11 '22 09:07 ktprime

如果30秒调用一次calibrate(),需要把init()的第二个参数也设到30秒。实际calibrate的周期不应该高于第二个参数。

MengRao avatar Jul 11 '22 09:07 MengRao

如果30秒调用一次calibrate(),需要把init()的第二个参数也设到30秒。实际calibrate的周期不应该高于第二个参数。

thanks reply

ktprime avatar Jul 11 '22 09:07 ktprime

  inline int64_t tsc2ns(int64_t tsc) const {
#if MULTI_THREAD_SDK
    while (true) {
      uint32_t before_seq = param_seq_.load(std::memory_order_acquire) & ~1;
      std::atomic_signal_fence(std::memory_order_acq_rel);
      int64_t ns = base_ns_ + (int64_t)((tsc - base_tsc_) * ns_per_tsc_);
      std::atomic_signal_fence(std::memory_order_acq_rel);
      uint32_t after_seq = param_seq_.load(std::memory_order_acquire);
      if (before_seq == after_seq) return ns;
    }
#else
    return base_ns_ + (int64_t)((tsc - base_tsc_) * ns_per_tsc_);
#endif
  }

单线程下能否这样改动?对性能追求极致,我的程序压测中每秒调用高达2百万次

ktprime avatar Aug 03 '22 01:08 ktprime

这样可以的

MengRao avatar Aug 03 '22 01:08 MengRao