数学假设
-
好多博主在介绍PTP协议时不介绍算法成立的前提条件和算法的误差来源,往往让初学者看的一头雾水,函数一定要写定义域(忘了喻大华老师怎么说的了吗,哈哈)。
-
PTP的核心算法依赖于计算主从时钟之间的路径延迟。它假设上行和下行路径的延迟是相等的(对称性)。实际的链路往往是非对称的(比如4G调制上行使用SC-FDMA,下行使用OFDMA,上下行采用的编码也不同,收发两端使用的光模块类型不同等等)。此外,如果网络中存在排队机制差异、不同速率的端口、或者使用了未开启透明时钟(Transparent Clock, TC)功能的中间设备,会导致上下行延迟不一致。这不是协议BUG,而是部署环境不符合协议理想假设,这些都会导致固定的时间偏差。
-
PTP 计算时间偏差(Offset)的核心公式基于一个理想假设:报文从主时钟到从时钟的时间 (下行)即
t_down = t_up。实际计算公式(见下部分推导)简化后是这样的:
Offset=(t2−t1)−(t4−t3)2 Offset = \frac{(t_2 - t_1) - (t_4 - t_3)}{2} Offset=2(t2−t1)−(t4−t3) -
如果网络是不对称的,假设下行比上行慢了 Δ\DeltaΔ(即 tdown=tup+Δt_{down} = t_{up} + \Deltatdown=tup+Δ),那么计算出的时间偏差就会包含一个固定的误差:
实际误差=Δ2 \text{实际误差} = \frac{\Delta}{2} 实际误差=2Δ -
这意味着:链路每产生 1 微秒的不对称,你的时间同步就会产生 0.5 微秒的固定偏差。在金融高频交易或 5G 基站协同中,几百纳秒的偏差都是不可接受的,这需要其他方法处理。
链路建模 & 消除主从偏差算法
- PTP协议是一种主从协议,从机根据收到的数据调整自己的时间以实现主机和从机时间的同步。

-
需要满足Slave_Time=Master_Time+Offset,这是主机收到的从机发出的数据才是以主机为标准的时间。
-
t2−t1t_2-t_1t2−t1 为主从偏差offset和传输时间delay共同作用的结果(如果传输时间为零,t2−t1t_2-t_1t2−t1就是真正的时间偏差)。
t2−t1=offset+delayt_2-t_1 = offset+delayt2−t1=offset+delay
t4−t3=−offset+delayt_4-t_3 = -offset+delayt4−t3=−offset+delay -
所以:
delay=t4−t3+t2−t12,offset=t2−t1−t4+t32delay=\frac{t_4-t_3+t_2-t_1}{2}, offset = \frac{t_2-t_1-t_4+t_3}{2}delay=2t4−t3+t2−t1,offset=2t2−t1−t4+t3
示例


建模代码 Drawio
<mxfile host="65bd71144e">
<diagram id="HqQHhHFjKBk7rr2WU10p" name="Page-1">
<mxGraphModel dx="448" dy="429" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="3" value="" style="endArrow=none;html=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="80" y="280" as="sourcePoint"/>
<mxPoint x="80" y="110" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="4" value="" style="endArrow=none;html=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="187" y="280" as="sourcePoint"/>
<mxPoint x="187" y="110" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="5" value="" style="endArrow=classic;html=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="90" y="120" as="sourcePoint"/>
<mxPoint x="175" y="153" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="6" value="" style="endArrow=classic;html=1;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="90" y="143" as="sourcePoint"/>
<mxPoint x="177" y="177" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="7" value="" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="225" y="123" width="115" height="170" as="geometry"/>
</mxCell>
<mxCell id="8" value="从机接收到的时间戳" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="217.5" y="90" width="130" height="30" as="geometry"/>
</mxCell>
<mxCell id="9" value="" style="endArrow=classic;html=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="180" y="211" as="sourcePoint"/>
<mxPoint x="90" y="251" as="targetPoint"/>
<Array as="points">
<mxPoint x="110" y="241"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="10" value="<font style="font-size: 16px;">t<sub style="">1</sub></font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="40" y="100" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="11" value="<font style="font-size: 16px;">t</font><font style="font-size: 13.3333px;"><sub>2</sub></font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="172" y="136" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="12" value="<font style="font-size: 16px;">t</font><font style="font-size: 13.3333px;"><sub>3</sub></font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="171" y="196" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="13" value="<font style="font-size: 16px;">t</font><font style="font-size: 13.3333px;"><sub>4</sub></font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="41" y="236" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="14" value="" style="endArrow=classic;html=1;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="91" y="253" as="sourcePoint"/>
<mxPoint x="180" y="270" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="17" value="<font style="font-size: 16px;"><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251);">t<sub>1</sub></font><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251); font-size: 13.3333px;">、</font><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251);">t</font><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251); font-size: 13.3333px;"><sub>2</sub>、</font><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251);">t</font><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251); font-size: 13.3333px;"><sub>3</sub>、</font>t</font><font style="font-size: 13.3333px;"><sub>4</sub></font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="225" y="250" width="115" height="30" as="geometry"/>
</mxCell>
<mxCell id="18" value="<font style="font-size: 16px;"><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251);">t<sub>1</sub></font><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251); font-size: 13.3333px;">、</font><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251);">t</font><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251); font-size: 13.3333px;"><sub>2</sub>、</font><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251);">t</font><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251); font-size: 13.3333px;"><sub>3</sub></font></font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="225" y="196" width="115" height="30" as="geometry"/>
</mxCell>
<mxCell id="19" value="<font style="font-size: 16px;"><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251);">t<sub>1</sub></font><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251); font-size: 13.3333px;">、</font><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251);">t</font><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251); font-size: 13.3333px;"><sub>2</sub></font></font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="225" y="159" width="115" height="30" as="geometry"/>
</mxCell>
<mxCell id="20" value="<font style="font-size: 16px;"><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251);">t</font><font style="color: rgb(63, 63, 63); scrollbar-color: rgb(226, 226, 226) rgb(251, 251, 251); font-size: 13.3333px;"><sub>2</sub></font></font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="226" y="132" width="115" height="30" as="geometry"/>
</mxCell>
<mxCell id="21" value="主机" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="48" y="274" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="22" value="从机" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="157.5" y="274" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="23" value="Sync" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="101" y="110" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="24" value="Follow_up" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="100" y="140" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="25" value="Dealy_Req" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="108" y="214" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="29" value="Dealy_Resp" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="107" y="244" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="30" value="从机时间需减去的Offset=(t<sub>2</sub>-t<sub>1</sub>-t<sub>4</sub>+t<sub>3</sub>)/2" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="80" y="293" width="250" height="30" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>