第一章:延迟的本质——从物理极限到软件开销

做高频交易的人,天天都在跟纳秒较劲。

你可能觉得,1纳秒能干嘛?光才走30厘米。但在交易系统里,1纳秒可能就是一笔订单的胜负手。我入行那会儿,带我的老工程师跟我说过一句话,我一直记着:「你优化的每一纳秒,都是在跟物理定律讨价还价。」

1.1 物理极限:光速不是你想用就能用

先说个最基础的。信号在铜线里传播,速度大概是光速的60%到70%。

为什么?因为介质有介电常数,信号得绕着走,不是直线。我当年在机房调试时,发现两台机器之间差了3米网线,延迟就多了15纳秒。你想想看,3米而已。

关键数据:

  • 真空中光速:299,792,458 m/s ≈ 30 cm/ns
  • 铜缆中信号速度:约 20 cm/ns(取决于介质)
  • 光纤中信号速度:约 20 cm/ns(折射率约1.5)

所以,物理距离是硬伤。你没法让信号跑得比光快。能做的只有缩短距离。这就是为什么交易所要把服务器放在离撮合引擎最近的地方——说白了,就是抢那几米的距离。

我见过一个极端案例。某家交易公司为了把服务器从机房A搬到机房B,距离缩短了50米,延迟降了250纳秒。就这250纳秒,他们每年多赚了上千万。嗯,你没听错。

1.2 硬件延迟:芯片、网卡、交换机都在拖后腿

光速是天花板,但硬件才是真正的瓶颈。

咱们拆开来看:

组件 典型延迟 说明
CPU L1缓存 ~1 ns 最快,但容量小
CPU L2缓存 ~4 ns 比L1慢,但更大
CPU L3缓存 ~10 ns 多核共享
内存访问 ~100 ns 这是大坑
网卡处理 ~1-5 μs 传统网卡,没优化
交换机转发 ~500 ns - 5 μs 取决于型号和配置

看到没?内存访问100纳秒,比L1缓存慢了100倍。你写代码时随便一个指针解引用,可能就是几十纳秒没了。我刚开始做优化时,总觉得内存够快,直到用perf工具一测,才发现大部分时间都花在等内存上。

个人经验: 我习惯在关键路径上禁用所有中断和上下文切换。为什么?因为一次上下文切换,少说几百纳秒,多则几微秒。在高频交易里,这就是灾难。

1.3 软件开销:操作系统和协议栈的「隐形税」

硬件延迟是明面上的,软件开销才是真正的隐形杀手。

你发一个网络包,从应用程序到网卡,中间要经过多少层?

  1. 应用程序调用 send()
  2. 进入内核态(系统调用)
  3. TCP/IP协议栈处理
  4. Socket层拷贝数据
  5. 网卡驱动排队
  6. DMA传输
  7. 网卡发送

每一步都有开销。我测过,标准Linux协议栈,一个UDP包的发送延迟,大概在5到10微秒。你想想看,光速走1公里才3.3微秒,你一个软件层就吃掉了几倍的时间。

为什么会这样?

说白了,操作系统是为通用场景设计的。它要保证公平、安全、稳定。但高频交易不需要这些。我们要的是极致性能,哪怕牺牲一点稳定性。

避坑指南: 我曾经在项目里直接用标准socket做高频交易,结果发现延迟抖动特别大。后来一查,是内核的软中断处理在作怪。从那以后,我再也不敢用标准协议栈了。改用DPDK或者Solarflare的OpenOnload,延迟直接降到1微秒以内。

1.4 延迟的组成:一张图看懂全局

咱们把上面说的整合一下。一个完整的数据包从A到B,延迟由这几部分组成:

数据包延迟组成结构图 发送端应用 协议栈处理 网卡发送 物理传输(光速限制) 接收端应用 协议栈处理 网卡接收 软件开销 (1-10 μs) 物理延迟 (距离/光速) 软件开销 (1-10 μs) 总延迟 = 发送端软件开销 + 物理传输延迟 + 接收端软件开销 注:实际场景中还包括交换机、路由器等中间设备延迟

这张图很直观。总延迟 = 发送端软件开销 + 物理传输延迟 + 接收端软件开销。

物理传输延迟你改变不了太多,除非你把服务器搬到交易所机房里。但软件开销,是我们可以下功夫的地方。

1.5 纳秒级竞赛的底层逻辑

理解了延迟的组成,你就明白为什么高频交易公司愿意花几百万买FPGA加速卡,为什么要把代码写成汇编,为什么要用内核旁路技术。

说白了,就是在跟物理极限赛跑的同时,把软件层的「隐形税」降到最低。

我个人的习惯是,做延迟优化时,先画一条完整的路径图。从数据产生到最终处理,每一步都标出延迟。然后问自己三个问题:

  • 这一步能不能去掉?
  • 这一步能不能用硬件做?
  • 这一步能不能并行?

大多数时候,答案都是「能」。只是你愿不愿意花那个成本。

核心观点: 延迟优化的本质,不是消除延迟(因为物理极限摆在那),而是把每一纳秒都花在刀刃上。你省下的每一纳秒,都是真金白银。

嗯,这一章就到这里。记住一句话:理解延迟,从物理极限到软件开销,你才算真正入了高频交易的门。


专注资料整理