rust 如何用单调时钟获取更精确的时间间隔

Wall Clock vs Monotonic Clock (墙上时钟 vs 单调时钟)

墙上时钟指的是我们日常意义上的时间,正如墙上的时钟代表的时间一样。单调时钟指的是某个时间点后开始计算的时间,单纯意义上的代表的时间是没有意义的。

操作系统上相对应的提供了两套时间,分别对应墙上时钟和单调时钟,操作系统用UTC来代表墙上时钟,UTC不支持闰秒, 并且可以认为更改,而且操作系统的时间是通过石英钟等来实现的,会由于温度等不可控因素导致时间发生偏移,
往往会通过网络时间协议NTP来进行同步,因此UTC天然存在着较大的误差,对于某些高性能场景的精准时间计算是不够的。

相对的,单调时钟保证时间一定是单调递增的,不存在时间往回拨。

Go语言怎么用单调时间计算花费时间

Go语言Time 结构体就定义了单调始终

type Time struct {
    // wall and ext encode the wall time seconds, wall time nanoseconds,
    // and optional monotonic clock reading in nanoseconds.
    //
    // From high to low bit position, wall encodes a 1-bit flag (hasMonotonic),
    // a 33-bit seconds field, and a 30-bit wall time nanoseconds field.
    // The nanoseconds field is in the range [0, 999999999].
    // If the hasMonotonic bit is 0, then the 33-bit field must be zero
    // and the full signed 64-bit wall seconds since Jan 1 year 1 is stored in ext.
    // If the hasMonotonic bit is 1, then the 33-bit field holds a 33-bit
    // unsigned wall seconds since Jan 1 year 1885, and ext holds a
    // signed 64-bit monotonic clock reading, nanoseconds since process start.
    wall uint64
    ext  int64
    ...

wall代表墙上始终,ext 代表单调时钟。
time.Sub内部先根据ext计算,如果没有ext,则根据UTC计算

 func (t Time) Sub(u Time) Duration {
    if t.wall&u.wall&hasMonotonic != 0 {
       te := t.ext
       ue := u.ext
       d := Duration(te - ue)
       if d < 0 && te > ue {
          return maxDuration // t - u is positive out of range
       }
       if d > 0 && te < ue {
          return minDuration // t - u is negative out of range
       }
       return d
    }
    d := Duration(t.sec()-u.sec())*Second + Duration(t.nsec()-u.nsec())
    // Check for overflow or underflow.
    switch {
    case u.Add(d).Equal(t):
       return d // d is correct
    case t.Before(u):
       return minDuration // t - u is negative out of range
    default:
       return maxDuration // t - u is positive out of range
    }
 }

大概是根据单调时间来计算花费的时间。

package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Now()
	time.Sleep(time.Second)
	fmt.Printf("have past %f seconds.", time.Since(t).Seconds())
}

rust语言怎么计算单调时间

使用std::Instant:now()

use std::time::{Duration, Instant};
use std::thread::sleep;

fn main() {
   let now = Instant::now();
   sleep(Duration::new(2, 0));
   println!("{}", now.elapsed().as_secs());
}

第三方库提供了更高性能的实现,有Coarse Time的实现coarsetime::Instant::now()以及基于Time Stamp Counter(TSC)寄存器的tikv/minstant库。

参考

posted @ 2022-02-20 20:51  yihailin  阅读(309)  评论(0编辑  收藏  举报