linux 定时器_定时器: 石心

定时器: 石心

在看 Node http 模块文档的时候, 才留意到 server.timeout 这个属性, 本想简单介绍一下, 但是在梳理过后发现关于 timeout 有庞大的内容支撑: server.timout -> node core timers -> uv timers -> linux msleep/hrtimer -> clocksource -> tsc -> cmos rtc -> clock cycle, 所以拆分成几部分大致做下介绍, 期望定时器系列结束之后, noder 能够大致明白: clock cycle 是如何驱动 linux的msleep/hrtimer;linux 的 timers 与 uv timers 的关系;node timers 与 uv timers的关系。

定时器是编程中运用最广的特性之一, 那么定时器实现的基本原理是什么呢?无论多么复杂计算机,当一层层退去她的外衣,她的内核只是一块可以发出固定频率脉冲的石心(石英), 好比人类的心脏,通过跳动给整个躯体提供能量和信号。

周期 与 精度

时钟周期, CPU周期[min(取指令)], 指令周期[取指令+执行指令], 微指令周期

9e2b7c12ffc7251bbf3336f02847fdb3.png

在 intel haswell 微架构内核架构中, 一条指令通常会被分解为多条微指令, 一个时钟周期,理论上最多可以并行执行8个微指令。

时钟周期与时间关系:

频率(HZ)11K1M1G1000G
时间(/Hz)1s1ms1us1ns1ps

目前普通的计算机CPU频率都在GHz级别, 以鄙人电脑为例: Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz, 意味着每秒钟有 1.6e9 次时钟周期。一个时钟周期大约为 0.625ns,所以目前来说普通的机器的定时器精度最多只能达到 ns 纳秒级别,那精度到底是 1n,10ns, 100ns 级别?要解决这个问题,需要从(微)指令的周期说起。在 linux 内核中 ,timer 最底层(本质是计数器)的一个指令是 ADD 1, 纵然在流水线的加持下,也避免不两个最基本的且具有先后管线的微指令: 运算和回写,所以最小的运算操作都需要0.625ns*2 = 1.25ns ,那么目前定时器最大应该在几个纳秒左右。

原本期望能够大概算出 linux 的 hrtimer 的精度范围, 实在因为 CPU 和 hrtimer 太复杂,个人知识有限,无法估计出来。目前 intel 最高睿频 10GHz 的情况下,如果如果能在10个时钟周期内完成一次while-schedule循环,也许。。。

本质 --- while + schedule

讲一个笑话: 双11凌晨开始大促销

while (true) {
 const now = new Date();
 if (now === '双11凌晨') {
  break;
 }
}
开始优惠();

虽然该程序或许存在一点点阻塞问题,但不可否认可以实现定时, 其实这就是定时器的本质。

加入非阻塞

while (true) {
 const now = new Date();
 if (now === '双11凌晨') {
  break;
 }
 schedule();// 调度让出 cpu 操作
}
开始优惠();

支持多个定时器

const timers = Some Data Structur[timer];
。。。
while (true) {
    const latest_timer = timers.peek(); // get the latest timer
 if (latest_timer && latest_timer === '双11凌晨') {
  break;
 }
 schedule();// 调度让出 cpu 操作
}
开始优惠();

剩余部分就是考虑在什么场景下,采用什么数据结构来保存定时器数据,从而可以实现C|U|R|D的最优(通常是时间最优)

参考

CPU流水线的探秘之旅

64-ia-32-architectures-optimization-manual

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值