精华内容
下载资源
问答
  • 聚积科技将时钟反向引擎用于近新推出的三信道恒流LED驱动器-MBI6020,以确保LED建筑照明系统的传输能力。由于LED建筑照明系统的讯号传输常常会随着时间或长距离传输而造成讯号的不稳定,因此特别需要稳定可靠的长...
  • 聚积科技将时钟反向引擎用于最近新推出的三信道恒流LED驱动器-MBI6020,以确保LED建筑照明系统的传输能力。由于LED建筑照明系统的讯号传输常常会随着时间或长距离传输而造成讯号的不稳定,因此特别需要稳定可靠的长...
  • 事由:RF测试时,发现U903无信号输入,只供电时,有输出信号,且会干扰RF指标
  • python自制海龟时钟

    2020-07-24 15:11:42
    12岁的小学生来自制海龟时钟咯 import turtle from datetime import * # 抬起画笔,向前运动一段距离放下 def skip(step): turtle.penup() turtle.forward(step) turtle.pendown() def mkHand(name, length): ...

    12岁的小学生来自制海龟时钟咯

    import turtle
    from datetime import *
    
    # 抬起画笔,向前运动一段距离放下
    def skip(step):
        turtle.penup()
        turtle.forward(step)
        turtle.pendown()
    
    def mkHand(name, length):
        # 注册Turtle形状,建立表针Turtle
        turtle.reset()
        # 先反向运动一段距离,终点作为绘制指针的起点
        skip(-length * 0.1)
        # 开始记录多边形的顶点。当前的乌龟位置是多边形的第一个顶点。
        turtle.begin_poly()
        turtle.forward(length * 1.1)
        # 停止记录多边形的顶点。当前的乌龟位置是多边形的最后一个顶点。将与第一个顶点相连。
        turtle.end_poly()
        # 返回最后记录的多边形。
        handForm = turtle.get_poly()
        turtle.register_shape(name, handForm)
    
    def init():
        global secHand, minHand, houHand, printer
        # 重置Turtle指向北
        turtle.mode("logo")
        # 建立三个表针Turtle并初始化
        mkHand("secHand", 135)
        mkHand("minHand", 125)
        mkHand("houHand", 90)
        secHand = turtle.Turtle()
        secHand.shape("secHand")
        minHand = turtle.Turtle()
        minHand.shape("minHand")
        houHand = turtle.Turtle()
        houHand.shape("houHand")
    
        for hand in secHand, minHand, houHand:
            hand.shapesize(1, 1, 3)
            hand.speed(0)
    
        # 建立输出文字Turtle
        printer = turtle.Turtle()
        # 隐藏画笔的turtle形状
        printer.hideturtle()
        printer.penup()
    
    # 绘制表盘
    def setupClock(radius):
        # 建立表的外框
        turtle.reset()
        turtle.pensize(7)
        for i in range(60):
            # 向前移动半径值
            skip(radius)
            if i % 5 == 0:
                # 画长刻度线
                turtle.forward(20)
                # 回到中心点
                skip(-radius - 20)
    
                # 移动到刻度线终点
                skip(radius + 20)
                # 下面是写表盘刻度值,为了不与划线重叠,所以对于特殊位置做了处理
                if i == 0:
                    turtle.write(int(12), align="center", font=("Courier", 14, "bold"))
                elif i == 30:
                    skip(25)
                    turtle.write(int(i/5), align="center", font=("Courier", 14, "bold"))
                    skip(-25)
                elif (i == 25 or i == 35):
                    skip(20)
                    turtle.write(int(i/5), align="center", font=("Courier", 14, "bold"))
                    skip(-20)
                else:
                    turtle.write(int(i/5), align="center", font=("Courier", 14, "bold"))
                
                # 回到中心点
                skip(-radius - 20)
            else:
                # 画圆点
                turtle.dot(5)
                skip(-radius)
            # 顺时针移动6°
            turtle.right(6)
    
    def week(t):
        week = ["星期一", "星期二", "星期三",
                "星期四", "星期五", "星期六", "星期日"]
        return week[t.weekday()]
    
    def date(t):
        y = t.year
        m = t.month
        d = t.day
        return "%s %d%d" % (y, m, d)
    
    def tick():
        # 绘制表针的动态显示
        t = datetime.today()
        second = t.second + t.microsecond * 0.000001
        minute = t.minute + second / 60.0
        hour = t.hour + minute / 60.0
        secHand.setheading(6 * second)
        minHand.setheading(6 * minute)
        houHand.setheading(30 * hour)
    
        turtle.tracer(False)
        printer.forward(65)
        printer.write(week(t), align="center",
                      font=("Courier", 14, "bold"))
        printer.back(130)
        printer.write(date(t), align="center",
                      font=("Courier", 14, "bold"))
        printer.home()
        turtle.tracer(True)
    
        # 100ms后继续调用tick
        turtle.ontimer(tick, 100)
    
    def main():
        # 打开/关闭龟动画,并为更新图纸设置延迟。
        turtle.tracer(False)
        init()
        setupClock(160)
        turtle.tracer(True)
        tick()
        turtle.mainloop()
    
    if __name__ == "__main__":
        main()
    

    我是12岁小学生,原创不易,求打赏

    展开全文
  • Delphi 时钟控件及代码实例,BmpClock模拟钟表组件,自由设置表针的长度,反向长度,添加位图背景,透明位图,可以设置纯颜色背景;使用双缓冲消除闪烁,可以使用此控件生成一些漂亮的时钟样式,比如圆形的时钟,包括...
  • 专用集成电路的设计分为正向设计和反向设计2大类。反向设计有样品可以解剖甚至仿效,实质上是一种仿制型的设计。与反向设计相比,正向设计在设计上有较大的难度,他是面向应用对象,以满足用户要求为目的的设计。...
  •  与三次泛音和反向蚀刻技术相比,SAW振荡器具有较高的可靠性和稳定性,可提供的时钟抖动,同时没有主动抖动(active dip),从而可降低误码率并提高系统性能。  时钟抖动是高速设计中普遍面临的问题,XG-1000的...
  • 反向器是一个简单的器件,用一个继电器就... 振荡器又常被称为时钟,因为它的输出在0、1之间按固有的规律交替变化。 振荡器从一个初始状态经过一段时间又回到这个状态;这个时间间隔定义为振荡器的一个循环,又叫周期
  • 在quartusII8.0中为ALTERAFPGA设置一个分频器(计数器) 输入时钟48Mhz ... 3 ** 时钟计算:9600*5000=48000000,,48Mhz的时钟累加5000次获得9600Hz的时钟,由于去的的clk的反向所以最终获得9600Hz的...

    在quartusII8.0中为ALTERAFPGA设置一个分频器(计数器)

    输入时钟48Mhz

    输出时钟9600HZ

     1 /* 实验名称: 计数器
     2 ** 程序功能: 将48Mhz的时钟分频为9600Hz
     3 ** 时钟计算:9600*5000=48000000,,48Mhz的时钟累加5000次获得9600Hz的时钟,由于去的的clk的反向所以最终获得9600Hz的时钟需要累加2500次
     4 */
     5 
     6 module Conter_500
     7 (    CLK_48MHz,
     8     Reset,
     9     CLKout
    10 );
    11 
    12     input CLK_48MHz;    //系统时钟50MHZ
    13     input Reset;        // 全局复位,低电平有效
    14     output CLKout;      //CLK时钟输出(9600)
    15 
    16     //2500 => 0x9c4 => 4*3  = 12位
    17     reg[11:0] cnt;       //定义计数器寄存器
    18     reg clkout;         //定义输出寄存器
    19 
    20     //计数器程序块
    21     //always :对某些信号的变化感兴趣
    22     //posedge : 表示CLK_48MHz 上升沿会进入程序块
    23     //negedge : 表示Reset   下降沿会进入程序块
    24     always@(posedge CLK_48MHz or negedge Reset)
    25         begin
    26         if(1'b0 == Reset)             //当Reset引脚低电平表示复位
    27             cnt <= 12'd0;                //复位时,值计数器的值为0
    28         else if(cnt == 12'd2499)        //当计数达到500时(因为计数从0开始)
    29             begin
    30             cnt <= 12'd0;                //计数器值置0,避免溢出
    31             clkout = ~clkout;           //输出clk反向
    32             end
    33         else 
    34             cnt <= cnt + 1'b1;          //计数器计数(累加)
    35         end
    36         
    37         assign CLKout=clkout;         //将clkout寄存器输出连接至实际的CLKOUT(引脚)
    38         
    39 endmodule

    在project Navigator的Files下如图:(现将DIVclk.v添加至Files中,右键Files会有相应的提示)

    右键DIVclk.v

    在project navigator 中的file 目录下找到源文件,右键点击源文件,选中 create symbol files for current file.
    QuartusII会先编译DIVclk.v,无错误后会生成DIVclk的原理图文件,生成的原理图文件在DIVclk的添加的工程中。

     

    
    

    转载于:https://www.cnblogs.com/BigOBlue/p/7908973.html

    展开全文
  • 而客观上,受限于服务器本身的时间源设备精度以及内核时钟系统的软件设计实现等多种复杂因素制约,常见的服务器秒级别的设备时钟误差大约在万分之二左右,而累积误差会出现正反向补偿,根据经验观测值,一年存在至少...

    背景
    BIGO的服务器分布在全球各地,各种服务如分布式追踪等都对全球机器存在时钟对齐的需求。而客观上,受限于服务器本身的时间源设备精度以及内核时钟系统的软件设计实现等多种复杂因素制约,常见的服务器秒级别的设备时钟误差大约在万分之二左右,而累积误差会出现正反向补偿,根据经验观测值,一年存在至少分钟级别的时钟误差。
    此类问题最常见的解决手段就是接入网络授时服务如NTP,但是作为一个全球分布几万+服务器的公司,简单接入NTP服务,并不能彻底解决全球时钟对齐的问题。
    BIGO的服务器很早期就接入了time.nist.gov的NTP网络时间同步服务,但是观测到公司内部的机器普遍存在百毫秒级别的时钟误差,单机视图存在时间跳变等问题,而且误差分布几乎是随机的,同机房内部都可能出现极大误差。
    基于以上现状,结合BIGO的业务需求,我们的全球时钟true time服务开启调研和建设。在业界相关领域,google的spanner论文有提到true time服务的建设,facebook也有公开过chrony时钟对齐服务解决方案。前者核心是依赖全球多机房部署原子钟+GPS构建了一个双层的架构,配合Marzullo变种算法来提供7ms时间区间服务。而后者本质上也是基于原子钟+GPS构建了一个最高可以达到16层的架构来提供true time服务。
    业界的现有技术方案,一方面存在硬件设备依赖,另一方面直接作为开箱即用的时间源在BIGO实际场景会制约我们的服务部署情况。于是我们基于外部NTP网络时间源+内部UTC时间源集群+多PTP集群的方案来构建了BIGO自己的全球true time时钟对齐服务,目标是在不依赖内部原子钟的前提下,把BIGO全球机器99.99%场景时钟误差控制在亚毫秒。
    该基础能力的建设,可以应用于BIGO内部不少场景:

    1. 解决分布式追踪场景的时间误差问题;
    2. 可以赋能BIGO的音视频优化直播帧时间戳跳变引起的卡顿问题,以及音视频和文件传输在重传准确率,拥塞控制等方向的提升;
    3. 解决时间跳变问题,提升BIGO基础框架等服务的稳定性,避免跳变引起的服务卡顿和挂死。

    NTP
    在了解时钟对齐相关原理时,NTP协议(Network Time Protocal)和相应的ntpd和ntpdate服务是必须要了解的。这里我们简单回顾一下相关原理。
    NTP协议的提出是为了解决这样一个问题:已知有一个基准服务器A,A的时间是准确的,怎么通过网络让B本地时钟跟A对齐?
    聪明的读者可能已经很快想到答案,B发包询问A,A把本地时间回给B就搞定了。但是问题没有这么简单,B->A的网络包延时d1,A->B的网络包延时d2,甚至A收到请求再回包过程的耗时d3都会导致B拿到的时间存在误差。
    针对此问题David L. Mills提出了NTP协议,最早出现在rfc958。
    在这里插入图片描述
    图1是单次NTP授时过程,首先B向A发送一个NTP包,包里包含了离开B的本地时间戳T1。A收到NTP请求包之后,依次记录包到达的本地时间戳T2,回包离开的时间戳T3,然后立即把包返回给B。B收到回包后,记录本地时间戳T4。
    其中我们把d1=T2-T1定义为上行延时,d2=T4-T3定义为下行延时。假设A-B的时钟绝对误差为diff,则有如下公式:
    d=d1+d2
    T2=T1+diff+d1
    T4=T3-diff+d2
    如上推算,A-B的时钟误差公式求解如下:
    在这里插入图片描述

    假设网络的上下行延时对等无波动,即d1=d2,则A-B的时钟误差近似值diff_appro跟diff相等,diff_appro的表达公式如下:
    在这里插入图片描述

    在单次的ntp对齐过程中,工程上往往基于diff_appro公式去计算A-B的时钟差,此时并未剔除上下行网络波动的影响,我们把diff称为A,B机对齐前时钟误差(简称前误差),把diff_appro-diff称为A,B机对齐后的时钟误差(简称后误差)。
    后误差的公式表达为diff_appro-diff=(d1-d2)/2,当d1或者d2等于d时,后误差最大为±d/2。
    NTP算法简单来说,就是基于diff_appro公式计算diff值,并对B机的时钟做出加diff_appro的调整,从而让B机的时钟向A机尽量对齐。对齐过程还会存在后误差(diff_appro-diff),后误差最大可以到±d/2。
    看到这里,可能聪明的读者要发出灵魂拷问了,A直接回时间给B,B完全不考虑任何误差直接使用A返回的时间设置为本机时间,这个过程存在的误差也就是d2而已,最大误差可以换算为d。这NTP绕了这么一圈,仅仅是把后误差缩小到到d/2而已,反正是不准,优化一半的精度似乎没什么价值。
    其实本质不是这样的,仅仅关注最大误差确实只优化了一半的精度。但是直接使用A返回的时间,A和B的时钟误差是恒等于d2的,而NTP的时钟误差本质上是跟上行延时和下行延时的差值成正比,网络延时是永恒存在的,而上下行延时差值(简述为网络波动)却不一定是永恒存在的,只要配合一些多次采样平滑调整,是可以基于NTP把时钟对齐的精度控制在比较理想的范围的。
    ntpd和ntpdate就是2种基于ntp协议封装的时钟对齐服务方式,前者利用了多时钟源以及一些平滑算法来规避对齐过程中的时钟跳变问题。而后者仅仅是对ntp协议过程的定期应用,容易存在误差和跳变。

    架构权衡与设计
    前面提到BIGO一开始全球机器都基于ntpdate接入了time.nist.gov,但是效果显而易见是不好的,普遍存在百毫秒误差,时钟跳变,误差无视机房,每个问题都很致命。
    那么简单换成ntpd会不会变好,我们的实践表明ntpd本机房同步误差可以控制在毫秒级别,但是跨大区同步存在10毫秒级别的误差,虽然对比ntpdate会有改善,但是这个效果还不够满足业务需求。或者我们的服务器可以物理距离跟ntp源保持靠近部署,但这不是一个好扩展的服务架构,也不符合我们全球多机房的运维现状。
    我们后续还尝试引入facebook的chrony(facebook提供的一种NTP时间源)作为时间源,其对比ntpd有更优秀的同步算法,但是我们验证跨大区同步的误差依然在6毫秒级别,主要原因在于公网跨大区上下行delay差异导致。此外chrony对第三方使用者的调优成本较高,其提供了如mindelay等十几种同步模式,缺乏最佳实践指引。
    简单总结一些权衡,如果要开箱即用一些ntp源服务,则BIGO的服务器部署会受到限制,如部署地点,同步频率等。因此我们在这一期放弃了全网直接使用相关ntp服务,而是开始在BIGO内部分层构建true time服务。
    架构上,我们要在没有内部原子钟设备的前提下,解决2个问题。

    1. BIGO的机器时间要和UTC时间保持较高精度的同步;
    2. BIGO各个内部机器之间的时间要尽量保持较高精度同步,且ping延时越小的机器之间精度要求越高。
      问题1即时间源的问题,google spanner里的true time的处理方式是依赖硬件设备,引入原子钟+GPS组成分布全球的master群,利用原子钟和GPS故障概率和故障原因存在差异这个特性做双保险保障master可用性。同时master和daemon(即slave)都会通过一些算法识别明显异常的时钟,从而在内部建设了一套全球高可用的高精度时间源。
      而BIGO在面对这个问题时,尚没有大规模的原子钟设备,为了低成本的解决时间源问题,最终我们选择了建设一个单机房的时间源,我们称为super master。super master为了保证可用性,应该是集群。Super master的时间并不是来自自身的时钟,而是基于ntpd跟一个物理距离上最接近的NTP源做时钟对齐。
      至此,我们在没有原子钟的情况下,得到了一个可用性对比google spanner里的 true time稍差一点的时间源。
      问题2,我们希望按机房分层建设架构。最终确定在每个机房建设一些master节点,本机房的其他节点(我们称为slave)只会跟这些master做时钟同步,基于PTP协议来进行。看到这里可能读者会疑惑,PTP是个什么协议,这里不急,后面会有篇幅对该协议做一个回顾,你可以先简单理解PTP是在NTP上做的一种工程优化,其比较适合子网内的高精度时钟同步(在毫秒内精度进一步提升),支持广播,单播等工作模式。
      最终,我们得到BIGO true time服务一期架构图如下:
      在这里插入图片描述

    架构里的相关名词解释如下:
    NTP源——基于ntpd或者ntpdate形式提供时钟对齐服务的标准机构(例如time.nist.gov是由美国国家标准技术研究所提供),NTP源的时间同步报文里包含的时间是UTC时间(等效于GMT格林威治时间)。
    Super Master——角色定位为BIGO内部的可靠UTC时间源,前面说了,super master是没有原子钟的,基于ntpd跟物理最近的NTP源做UTC时钟同步。Super master一期暂时是单机房的,后面为了更高的可用性,会规划多机房的分布式UTC源架构。
    Name Service——BIGO内部的分布式名字服务,具体架构不细讲了,可以对标Etcd等架构,这里该模块主要用于给master发现super master做ptp单播时钟同步用。
    Master——某个机房内的时钟源,仅仅服务本机房的节点。一个机房内可以有多个master存在。Master会定期基于PTP单播配合我们的平滑算法去super master做时钟同步,同时,也会秒级对子网内做ptp的sync广播达成master和slave的时钟同步。
    关于master的选举决策,这里涉及到PTP里的BMC算法,原则上一个机房不需要唯一的master,该算法不同于其他分布式强一致算法如paxos,不需要达成全局唯一共识。关于BMC选举master机制我们后面会展开讲解。
    Slave——机房里的普通服务器,会周期秒级收到同机房master的PTP sync同步广播,达成时钟同步,当前由于只会在同机房做时钟同步,该过程暂未做平滑处理。

    机房内Master选举
    提起Master选举,可能很多读者会想到Raft,Paxos等相关技术方案。而在我们这个具体的问题领域,关于在一堆机器里选出合适的主机作为master来成为时钟源,比较经典的是IEEE1588里的BMC(Best Master Clock)算法。
    该算法比较适合子网内部Master选举的特点,只负责选出确定的Master群,并动态保障slave一定可以较快找到可用的Master,但是不考虑slave使用的master是否是最优解,BIGO内部为该算法设计了保底策略,用于规避极端情况长期使用较差的master。
    BMC算法本身为每台机器设置了几个属性:
    1)机器优先级:根据机器属性赋予机器的一个优先级,值越小优先级越高;
    2)分组优先级:对机器进行分组,每个组有一个优先级值越小优先级越高;
    3)唯一标识:进程的唯一标识,一般使用MAC地址。
    BIGO这边由于子网天然是同机房的,所以1和2默认都是不配置的,基于保底策略来动态解决机器网络状况波动问题。
    原始的BMC算法选主流程如下:
    1) 进程接收子网内的master的广播信息,并加入自身的foreignMaster列表;
    2)进程根据foreignMaster列表信息(可能为空)和本进程信息通过BMC算法按机器属性选择出最优的master;
    3)如果进程成为master的话,则开始广播信息。
    在这里插入图片描述
    图3是选主过程的状态迁移图,子网内任何一台机器都会周期的check自身的foreignMaster列表,选出当前的自己的master(可以是自己),然后相应把自身角色设置为master(slave)。
    该算法集群多机状态收敛过程还是比较清晰简单的。

    1. 初始的时候,不考虑引入任何随机退让算法,子网内所有机器都没有收到任何master的announce请求,则会将自己提升为master,并开始广播自己的信息。此时,子网内全部机器都是master;
    2. 子网内的机器开始陆续收到子网内master的信息,在这过程中,不断执行bmc算法,进而将更优的进程设置为master,最后一般在几个广播周期内,整个集群的master,slvae状态达到稳定。
      下面的图4简要的展示了BMC算法从初始化到收敛过程:
      在这里插入图片描述

    总结来看,BMC算法优点就是快速,简洁,而由于选主条件是静态的(如MAC地址大小),无法保证选出的master是网络情况最优的,这种算法在子网内比较合适。
    为了保证该算法在网络变化后可以剔除掉明显异常的Master点,BIGO尝试引入网络波动保底策略。即在保持BMC算法主流程情况下,引入master->slave的网络波动情况来优化master选择策略。
    为什么基于网络波动来做选主决策,而不考虑网络延时大小,根据我们前面描述的NTP原理,读者应该清楚,时钟同步的误差受上下行网络差值影响较大,而延时的绝对大小是没有影响的。
    BIGO这边会基于PTP的delay过程(后面一节PTP协议会详细讲解),在本机维护slave跟他foreignMaster列表的机器的历史delay值集合——foreignMaster’s delay_list。然后基于标准方差公式计算每台master的delay方差S(关于方差的概念,本文不再赘述)。我们认为方差S可以较好的表达foreignMaster的网络波动。
    在原BMC选主过程,BIGO会额外判断目标master的方差S是否超出了阈值,如果是则会把该Master机器从slave的foreignMaster列表里暂时踢掉,当S恢复小于阈值后,会再加回foreignMaster列表,全过程对BMC选主机制没有任何收敛性相关的破坏。
    最后说一下,为什么BIGO不尝试改变BMC选主顺序条件,比如按照master的S大小来优先选主。主要基于2点考虑:

    1. 子网内机器间的网络状况一般都是平等,我们没有强烈的需求需要选出最优的master,我们需要做的是规避毛刺和异常节点;
    2. 改变BMC选主顺序,引入动态变量S来调整Master优先级,意味着每台slave机的Master优先级视图可以不一样,BMC简洁的Master收敛过程被破坏,我们需要很小心的去review整个算法的全过程,避免出现极端的Bug,而如1所述,这项工作的收益并不大。

    PTP
    单机房内部,master和slave之间通过PTP协议来完成时钟同步。这里简单回顾一下PTP协议,以及BIGO内部使用情况。
    首先,NTP的原理读者应该已经清楚了,那么我们可以认为PTP是尝试对NTP做工程落地的一种优化实现方式。PTP全称为Precision Timing Protocol,也是在IEEE1588里提出的。PTP主要解决了2个工程上的问题:
    1.解决NTP里面精准获取d1,d2的问题;
    2.怎么高效的在一个子网内对多个slave同步时钟的问题。
    先讲下问题1,精准获取d1,d2是什么意思呢?
    首先,PTP是基于UDP协议来通信的,我们把d1,d2定义为网络延时,但是在工程实现上,假如B给A发包,A给B回包,A发回包前获取本机时间T3‘的话,那么T3’=T3-UC。其中T3是网络包从内核发出去的时间,UC是A获取本机时间到回包从内核发出去的时间差,为什么会有UC存在,因为linux并不是一个实时操作系统。UC的耗时组成会很复杂,cpu调度的繁忙程度,缓冲到发送的耗时都会影响UC,且会动态变化。而真正的延时d2=T4-T3,如果仅仅把T3’打到包里回给B,那么B在计算d2的时候就会存在误差。
    关于问题2,PTP这边利用广播机制来主动对多个slave进行时钟同步,工程上具备容易配置,快速收敛(参考前面的机房内master选举算法过程),以及网络带宽和资源占用少等优点
    PTP具体同步过程分为delay机制和sync机制:
    在这里插入图片描述
    图5为PTP时钟delay机制的同步过程,该过程重点解决一个问题:工程上精准算A到B的网络时延delay值。
    为什么要算这个值呢?基于PTP子网同步的场景特点,PTP假设短时间内,一个子网的网络波动较小,即D1=D2,且D1值短时间内不会变化。基于这个假设,PTP后面可以以较低开销完成sync机制的时间同步。
    简单来说,PTP在一个子网内,slave会长周期的进行delay广播机制,该过程开销偏大。而master侧会短周期的进行sync机制,来达成对子网内全部slave的时钟同步,该过程开销相对小。
    回到delay机制过程本身,是怎么做到精准测算A到B的delay值呢。图中T1’,T2’,T3’,T4’都是PTP程序用户态可以拿到的时间,这些时间都含有误差。要精准测算delay,B就需要获取T1,T2,T3,T4,即req和resp从网卡发出,以及达到收包方内核协议栈的时间。
    先说T2和T4值,这2个值在udp包达到内核协议栈之后会记录下来,用户态可以拿到该时间。从B的视角,T4本身就可以拿到,T2可以让A的程序在回包的包体里带上。
    再来说T3,这个值的获取原理,是ptp delay机制需要广播发起的主要原因。PDelayResp包回包是广播到子网,由于是广播包,A自己也可以收到PDelayResp,基于回环广播特性此时A收到的PDelayResp包的到达时间就是该包的网卡发出时间,即T3。此时A只需要再发一个PDelayRespFollowUp包,包体里带上T3时间,则B就可以正确获取T3时间了。
    最后说T1,只要明白T3的获取原理,则类似T3,B本身获取T1也是基于PDelayReq包的回环达到时间判定。
    至此,基于公式delay = (T2-T1+T4-T3)/2即可在工程上完成精准测算A到B的网络时延delay值。
    在这里插入图片描述
    图6为PTP时钟同步的sync过程,该过程运行时,B已经成功获取到A到B的网络时延dealy。此时A作为master主动广播sync请求帮助B精准测算出A,B本地时钟差值offset。
    本次过程依然A,B只能拿到T1’,T2’,但是基于前面delay过程的描述,读者应该可以比较直接的知道如何获取到T1和T2。过程不再赘述,B可以直接拿到T2,而followup包会把T1带给B。
    于是我们知道T1+offset+dealy=T2,故A,B机器时钟误差满足offset=T2-T1-delay。B得到offset之后,修改本地时钟即完成了一次PTP的子网时钟对齐的过程。
    最后提一下,PTP本身的工程源码也存在一些乱序和时钟同步错误的bug,BIGO内部基于一个版本做了一些改造优化。

    跨机房同步
    Master机器周期跨机房与super master做时钟同步,是本架构里主要误差来源。BIGO内部跨机房,跨大洲以走公网为主,网络延时大,网络波动比较明显。即使内部建设很好的光纤内网,双向链路的延时对称性也不一定可以保证,在实际运行中受很多因素影响。
    在这一层实现上,BIGO基于ptp单播协议(这个不细讲了,就是ntp协议的工程实现)来做同步,但是该协议显而易见在网络波动下存在误差和跳变。
    针对这个问题,BIGO参考了Ntpd的平滑实现并加入自研的异常波动剔除算法,来优化ptp单播跨机房同步过程存在的误差和跳变,主要有2个策略:

    1. 当计算出offset(即ntp里的diff)在128ms以内时,对master本地时钟往super master时钟方向调整最多0.5ms。当计算出offset(即ntp里的diff)大于128ms时,默认忽略该offset,除非该offset持续了一个较大阈值周期(300s),才会基于此offset调整master时钟;
    2. 基于波动阈值x剔除无效同步。当本次ptp单播的delay比最近30次delay值误差大于阈值x,则本次ptp单播的结果不被应用,同时x相应增加。只有当前ptp结果被采纳,且offset值小于2ms,才会把x重置为初始值。
      策略1可以保证时钟对齐过程的平滑,同时时钟对齐导致的时钟回退问题也解决了。这里的0.5ms/s不是人为设置一个绝对值,而是调用linux内核封装的Phase-locked loop机制来对本机时钟进行调整。从而保证时间调整不会在应用上层体现为时间回退。该机制原理,本文不做展开。
      策略2可以剔除网络波动对同步结果的影响,有点类似chrony的mindelay机制。
      BIGO在上线该策略后,对比之前无平滑策略的ntpdate效果明显,在跨机房同步场景,比nptd和facebook的chrony效果也要更好,相关效果检验下面会完整阐述。

    效果评测与仿真
    关于精度和效果评测这个话题,业界如facebook的chrony内部声称做到0.1ms以内的的误差精度,而google的spanner里的true time是100%确信在7ms的区间内。BIGO在开展此项工作的一期目标是在没有内部原子钟的前提下,把99.99%场景误差精度控制在亚毫秒。
    关于精度的测算,本身就是一个跟全球时钟对齐同等难度的命题。
    为什么这么说呢,因为如果我们可以在上帝视角完美0误差识别任意2台机器的时间误差,那么也就代表着我们可以把任意2台机器的时间误差调整为0。
    已知比较好的评测手段,有facebook提到的基于1PPS(每秒脉冲数)来检测任意2台机器的时钟误差,该评测可以做到纳秒级的误差,但是对硬件有很多依赖,如需要在机器间铺设专用同轴电缆,需要定制的网卡硬件。
    这个话题,我们主要从2个方向来展开:评价指标和评价手段。
    首先关于用什么指标来评价集群内机器之间的时钟误差情况,比较直观的就是机器间误差的时间轴坐标图,基于坐标图我们抽象了2个主要指标:
    1)可用性——基于我们对误差精度的要求是是亚毫秒,则每秒进行一次机器间时钟误差判断,大于1ms则认为这1秒时钟服务不可用,最后可用时间占比即为可用性;
    2)最大误差值——机器间误差值波动过大,我们认为需要重点关注。
    评价手段这块,我们没有相关硬件来支撑我们做1PPS的效果评测,所以我们这里基于仿真的思路来做评测。
    我们仅仅观察同机房的2台机器A和B的时间误差,由于同机房机器ping 延时可以稳定在0.1ms以下,此时我们近似具备了较高精度观测误差的能力。然后我们仅仅先评测以下3个场景:
    1)A和B各自基于某种同步算法,跟本机房(或者同城)的时间源做时间同步,观测A和B的误差时间轴坐标图;
    2)A和B各自基于某种同步算法,跟远端跨大区的时间源做时间同步,观测A和B的误差时间轴坐标图;
    3)A基于某种同步算法,跟远端跨大区的时间源做时间同步,B基于相同同步算法,跟本机房(或者同城)的时间源做时间同步,观测A和B的误差时间轴坐标图。
    在这里插入图片描述
    图7简单描述了前面所说的3种评测场景。需要注意一点,待评测的UTC时间源可能是跟我们的机器在一个机房,也可能仅仅是同城,取决于待评测服务本身实际部署情况。
    我们再来关注怎么评测一个时钟同步算法在跨大区机器间的误差,比如图中A1和B2之间的时钟误差?
    软件层面这个问题看起来是无法评测的,但是我们先假设UTC时间源(外部原子钟设备)之间是没有毫秒级误差,那么A3和B3的时钟误差我们暂时可以基于0.1ms的精度进行评测,我们定义A3和B3的时钟误差为diff(A3,B3),则diff(A1,B2)近似等于 diff(A3,B3)。
    一句话总结,我们可用观测diff(A3,B3)的结果认为其实仿真表达了diff(A1,B2),等价于我们成功评测了一个时钟同步算法在跨大区机器间的误差(本质上还是有2套本机房外部原子钟UTC源加持,但是仅仅是做评测时依赖而已,我们的系统的机器部署实质不依赖外部UTC时间源的具体部署情况)。
    至此,我们已经具备不依赖内部硬件设备,在BIGO全球机房仿真评测同机房,跨大区机器的毫秒级时钟误差的能力。
    图8到图13分别为跨大洲和同机房情况下BIGO,NTP和facebook的chrony时钟同步误差测量表。
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述图8~图13为我们观测BIGO同机房机器,基于不同算法和不同区域源时钟同步之后,取得的误差表。全部场景都观测了3个小时,每秒观测一次,每张图都是1万个横轴坐标点。需要注意的是,ntpdate本身明显过于粗糙,我们认为不值得浪费时间进行对比,所以这里只对比了ntpd和facebook的chrony。
    此外,这里的对比结果不一定就代表facebook的chrony内部精度情况,仅仅表达了BIGO作为一个第三方,去依赖这些服务,我们能获得的精度能力。而且chrony本身提供了数十种参数来调优精度和波动,因为精力有限,我们对比时使用默认配置。
    在这里插入图片描述图14为我们对6张评测效果做的总结。
    前面3行是跨大洲场景的表现,以前面定义的可用性而言,ntpd和chrony直接使用都无法满足我们的可用性需求,而最大误差这块,BIGO自研架构下的机器时钟误差控制在0.5ms内,而直接接入ntpd有近10ms最大误差,接入chrony的误差接近6ms。
    后3行是同机房或者同大区的表现,此时BIGO自研架构下的机器时钟误差的可用性和最大误差依然是好过直接接入ntpd或者chrony的。其表达的含义为,即使BIGO选择限制自身的机房部署情况,做架构设计去适配ntpd和chrony源来复用他们提供的时钟对齐服务,效果依然不如当前版本的BIGO自研架构。

    总结
    总结一下BIGO在全球时钟同步服务的工作,在没有内部原子钟的前提下,基于双层架构设计,建设了稳定的内部UTC时间源。同时基于ptp单播配合平滑+异常剔除算法保证了第一层跨机房时钟同步精度控制在亚毫秒。然后在第二层机房子网内,基于ptp算法实现,优化了网卡发包到用户代码层的时间误差问题,进而把机房内的时钟精度在毫秒内进一步提升。
    最终我们收获了一个99.99%场景下,集群时钟误差都在亚毫秒精度的时钟服务,且随着ping值减少,同机房的精度有进一步的提升。该服务架构具备良好的内部可扩展性,不依赖外部NTP时钟源的部署和服务能力。同时我们提供了有效的评测手段来验证我们的毫秒级误差情况。
    该系统在内部UTC时间源的精度以及集群可用性,还有对抗上下行延时差值,高精度时钟评测等方向还有诸多工作待进一步展开优化,这些将规划到我们的后期工作中。
    该系统当前作为基础设施,为BIGO的全链路trace系统等多项服务提供时钟对齐保证,成功解决了负调用耗时等业务问题。

    展开全文
  • 51单片机 本机与时钟

    2020-06-21 23:53:40
    人话就是反向放大器能形成震荡电路(好像还能形成多种振荡电路),而震荡电路与时钟密切相关,记住这个就行了。 了解即可,说明很简单。 晶振具有压电效应,即在晶片两极外加电压后晶体会产生变形,反过来如...

    P0口作输出口用时,需加上拉电bai阻。P0口有复用功能。当对du外部存储器进行读写操作时,P0口先是

    提供外部存储器的低8位地址,供外部存储器地址锁存器锁存,然后充当数据线,用于写出或读入数

    据。P1口、P2口只是普通IO口。P0口没有内部上拉电阻外,其他三个都有内部上拉电阻。

    P1 就没多少功能,就是个准双向I/O口。

    P3口除了是个准双向I/O口外。第二功能很重要P3.0 (RXD)串行数据接收端,P3.1 (TXD)

    串行数据发送端,P3.2 (INT0)外部中断0输入,P3.3 (INT1)外部中断1输入;

    P3.4(T0)Timer0计数器输入,P3.5(T1)Timer1计数器输入,P3.6(WR)写外部存储器的脉冲

    输出,P3.7(RD)读外部存储器的脉冲输出。

    P3的8条口线都定义有第二功能。 

    人话就是反向放大器能形成震荡电路(好像还能形成多种振荡电路),而震荡电路与时钟密切相关,记住这个就行了。

    了解即可,说明很简单。

    晶振具有压电效应,即在晶片两极外加电压后晶体会产生变形,反过来如外力使晶片变形,则两极上金属片又会产生电压。如果给晶片加上适当的交变电压,晶片就会产生谐振(谐振频率与石英斜面倾角等有关系,且频率一定)。晶振利用一种能把电能和机械能相互转化的晶体,在共振的状态下工作可以提供稳定、精确的单频振荡。在通常工作条件下,普通的晶振频率绝对精度可达百万分之五十。利用该特性,晶振可以提供较稳定的脉冲,广泛应用于微芯片的时钟电路里。晶片多为石英半导体材料,外壳用金属封装。

    就是说能够提供绝对稳定的脉冲,脉冲的确是重要的。而它的组合电路确保它能够稳定输出脉冲。

    不知道人家是如何分频的,但是这个概念还是清楚的,反正时钟就是P1和P2了。

    震荡周期是晶振硬件震荡的周期

    时钟周期是震荡周期的两倍,因为分成了P1节拍和P2节拍了,通常在P1节拍完成算数操作,在P2节拍完成内部寄存器之间的传送操作,P1和P2的确是间隔的,只接收P1势必会变成两倍的。时钟周期又叫做状态周期或状态时间S。

    机器周期由6个状态组成,是一条指令的几个操作步骤中的一个,可以理解为原子操作吧,毕竟一个指令的确是分步骤的。

    指令周期是执行指令的全部时间,通常为1~4个机器周期。

     

    展开全文
  •  与三次泛音和反向蚀刻技术相比,SAW振荡器具有较高的可靠性和稳定性,可提供最低的时钟抖动,同时没有主动抖动(active dip),从而可降低误码率并提高系统性能。  时钟抖动是高速设计中普遍面临的问题,XG-1000...
  • 时钟万年历说明书

    千次阅读 2015-03-13 15:18:54
    * 反向计时器 * 音乐欣赏 * 生日提醒 基本操作 1. 装入3节7号电池,进入“正常显示状态”,并播放1首音乐。LCD显示为:12:00 1/1 THU 2. 在正常显示状态下,按“MODE”键分别进入相应的功能: 正常状态 -> 12...
  • **什么是设置伪路径?**伪路径是指该路径存在...**注意的是:**伪路径的设置是单向的,如果两时钟之间存在相互的数据传输,则需要再反向设置一次伪路径。 举例如何设置伪路径: 在异步时钟的位置右击选择设置伪路径即
  • 向前运动一段距离放下defskip(step):turtle.penup()turtle.forward(step)turtle.pendown()defmkHand(name, length):#注册Turtle形状,建立表针Turtleturtle.reset()#先反向运动一段距离,终点作为绘制指针的起点skip...
  • Verilog学习心得之五-----时钟分频器

    千次阅读 2018-09-27 00:18:29
    时钟整数分频分为奇数和偶数分频,偶数分频较为简单,假如需要进行偶数为N倍分频,则只需对原输入时钟进行从零开始计数count,当计数值count计数到N/2-1,只需将输出时钟反向即可,RTL代码和测试波形如下: ...
  • 利用NGINX搭建反向代理服务器,对于测试环境可以有如下作用: 1. 统一各应用的服务地址,方便应用环境快速切换。 2. 按照NGINX标准格式记录应用访问的日志,解决了长流程交易各应用时钟不一致对于日志分析的影响 3. ...
  • 数字信号编码是要解决数字数据的数字信号表示问题,即通过对数字信号进行编码来表示数据。...特点:每个时钟周期的中间都有一次电平跳变,这个跳变做同步之用,能携带时钟信号,且可表示有没有数据传输 ...
  • ValueTime-crx插件

    2021-03-23 07:49:44
    将新标签页替换为显示当天剩余时间的页面(反向时钟类型)。 更新:黑暗和光明模式添加,点击该按钮之间切换模式。 这是一个替换新标签的网页。 它显示当天的动机报价和剩余时间,以保持一个动力 完成他的目标,并...
  • SSD1306(OLED屏幕)反向显示问题

    千次阅读 2018-08-29 10:42:58
    昨天接手一个需要维护的项目,其中有一个OLED屏幕显示总是反的,下面是原来的驱动程序: ... //设置时钟分频因子,震荡频率 Write_IIC_Command(0x50); //[3:0],分频因子;[7:4],震荡频率 Write_IIC_Command(0xA8); ...
  • MAX2470/MAX2471的基本工作原理MAX2470/MAX2471是一种灵活的低成本、高反向传输隔离缓冲放大器,是分立式或基于模块的VCO设计的理想选择。两者都具有50差分输出,能驱动一路差分(平衡)负载或两路独立的单端(不平衡) ...
  • 发现在并发环境下mysql数据库的压力时钟很大,一台服务器上面不仅仅要跑java的jar包程序,还要承受高并发访问数据库的压力。这样的压力都在同一台服务器上显然存在缺陷。所以我们可以购买多台服务器。 一台专门用来...
  • 对Glorious GMMK TKL键盘进行反向工程(ISO布局) 对于此过程,我使用在提供的资源。 GMMK TKL ISO使用eVision VS11K13A,它是Sonix SN32F268的更名。 还使用了两个控制RGB的支持芯片,即Sonix SLED1734X品牌的...
  • MAX2470/MAX2471的基本工作原理MAX2470/MAX2471是一种灵活的低成本、高反向传输隔离缓冲放大器,是分立式或基于模块的VCO设计的理想选择。两者都具有50差分输出,能驱动一路差分(平衡)负载或两路独立的单端(不平衡) ...
  • 时钟配置三. 主要代码1. 定义定时器控制类,以及相关宏定义2. 新建定时器控制类对象,并声明需要实现的方法3. 实现具体方法4. 声明全局变量,以及全局方法 一. 前言 测试时所使用的 MCU 是:STM32F103C8TX 测试时...
  • 电路用 PNP管来反向驱动并且控制列扫描信号来选择哪个数码管。而且所有的 6 个数码管的“段选信号”(LEDA … LEDH)都共用驱动引脚(LED_A~LEDH)。数码管的所有驱动信号都是“低电平有效”。具体的原理图设计如下图...
  • 向前运动一段距离放下defskip(step):turtle.penup()turtle.forward(step)turtle.pendown()defmkHand(name, length):#注册Turtle形状,建立表针Turtleturtle.reset()#先反向运动一段距离,终点作为绘制指针的起点skip...
  • 时钟配置三. 主要代码1. 定义定时器控制类,及相关宏定义2. 新建定时器控制类对象,并声明需要实现的方法3. 实现具体方法4. 声明全局变量,以及方法四. 测试1. 正反通道同时输出测试1.1 测试代码1.2 测试效果2. ...
  • 在集成电路设计中,需要使芯片上内部时钟和外部时钟同步,希望在外部时钟输入的高频率下使用芯片的内部时钟。基于以上两点,锁相环常常用于产生芯片上的内时钟。但是随着处理器频率的提高,传统的数字锁相环已经不能...
  • 毕业生简历模板

    2012-03-18 09:54:36
    STC12C5A32S2内部有一个高增益反向放大器,用于构成振荡器。但要形成时钟脉冲还要另加电路。STC12C5A32S2的时钟产生方法有以下两种: (1)内部时钟方式 利用芯片内部的振荡器,然后再引脚XTL1,XTL2的两端跨接晶体...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 210
精华内容 84
关键字:

反向时钟