做市商的核心循环里,一次 tick-to-trade 只要多出几十纳秒的抖动,纸面上的正期望就会被对手方直接吃掉。
我起初以为只要把策略逻辑写得足够精简,现代 5 GHz 的 CPU 就能把几百条指令压进 20–100 纳秒的理论下限;后来真正把热路径放到真实内核和网卡上跑,才发现操作系统、缓存、分支预测这些“日常看不见”的机制,才是真正把延迟拉到微秒级的元凶。

低延迟交易本质上是实时系统:目标不是最大化吞吐,而是保证每一次事件处理的延迟分布足够窄。汽车安全气囊要求 100 % 在碰撞前打开,做市同样要求 tick-to-trade 的抖动接近于零——任何不可控的额外延迟都会把盈利策略变成亏损策略。CPU 本身并不是为消除抖动而设计的,但通过把资源换时间,可以把它逼近指令级下限。

操作系统调度与系统调用:把确定性先交出去

普通程序把 CPU 核心当成共享资源,由内核用时间片轮转。一旦时间片用完,或者更高优先级任务出现,当前线程就被抢占。一次上下文切换的开销是几百条指令,还要把缓存全部弄脏。即使关掉抢占、把核心空出来,切换本身的开销依然存在。

解决办法是彻底放弃共享:把交易进程绑到隔离核上,每个核只跑一个永不 yield 的实时线程。线程在空闲时持续轮询,同时把热数据一遍遍扫过 L1/L2,让缓存始终保持“热”状态。代价是空转时 CPU 和功耗被完全烧掉,但做市商眼里电力和机柜冷却本来就是边际成本。

网络读写同样不能再走 read()/write()。系统调用至少要保存寄存器、切换到内核态,再加几百条指令。用户态协议栈(目前主流仍是 Solarflare 这类方案)把收发包直接放进进程地址空间,把内核彻底踢出热路径。日志、指标、审计则全部异步挪到旁路,保证主循环只做一件事。

缓存未命中:数据与指令必须同时“住在 L1”

现代 CPU 的延迟阶梯非常陡:L1 命中大约 1–4 周期,L2 十几周期,L3 几十周期,到内存就是上百周期。热路径里任何一次 miss,整条流水线就停下来等。

保持数据热的方法很直接:空闲时循环访问订单簿、持仓、风控参数,强制把它们留在 L1。数据结构必须紧凑、按缓存行对齐,避免 false sharing。跨核通信则用固定大小的环形缓冲区(LMAX Disruptor 思路)单向传递消息,彻底消除共享写带来的缓存一致性流量。

指令侧同样要“热”。函数调用、虚函数、远距离跳转都会让指令缓存 miss,流水线重启。热路径必须在编译期全部内联,最终汇编看起来像一条没有跳转的直线。运行时多态在这里直接禁用,改用编译期模板或静态分发——用代码体积换确定延迟。

分支预测:happy path 才是唯一需要保护的路径

流水线靠分支预测器猜测 if/else 的走向。猜对了继续跑,猜错了整条管道清空重来。普通软件追求整体命中率,交易热路径却只关心“真正下单”那条极少数路径。绝大多数 tick 根本不会产生订单,这种分布正好和预测器训练数据相反。

因此热路径里能消掉的条件就全部消掉:用位运算、查表、预计算把决策提前到编译期或冷路径。剩下的极少数分支,用 profile-guided 或显式 hint 告诉编译器“这条路几乎从不走”。结果是 happy path 的延迟分布被压到极窄,unhappy path 的额外开销可以接受。

把四类抖动源按“可消除程度”排个序,就能看清工程优先级:

抖动源 典型额外延迟 消除手段 资源代价 生产环境优先级
上下文切换 数百指令 + 缓存失效 核隔离 + 自旋线程 CPU 空转 最高
系统调用 数百指令 + 内核切换 用户态网络栈 + 旁路 I/O 专用网卡驱动 最高
数据/指令缓存 miss 10–数百周期 缓存预热 + 紧凑结构 + 全内联 代码体积、内存带宽
分支预测失败 流水线重启 消除条件 + 编译期决策 代码复杂度

这张表背后的判断很简单:前两项是“系统级开关”,关掉之后才能谈后面的微架构优化;后两项则是“把业务逻辑本身压到指令下限”的最后一公里。

真正落地时,我通常先搭一个最小可测量的 harness:把热路径包在 tight loop 里,用 perf 或 PMU 计数器盯着 cache-miss、branch-miss、context-switch。每改一处就重新 profile,确认数字真的往下走。几轮之后,原本几百微秒的 naive 实现往往能掉到亚微秒,再往下才是真正需要汇编级微调的部分。

低延迟交易并没有神秘配方,只是把实时系统的经典原则推到了极限:用确定性换吞吐,用资源换时间,用编译期决策换运行时猜测。对大多数非做市场景,哪怕只吃掉前两层抖动,延迟也能降一个数量级。真正难的是把这些原则写进日常开发习惯,而不是等出了事故再回头补。

你现在的热路径里,还有没有被系统调用或共享缓存悄悄拖住的地方?欢迎直接说具体场景,我们一起把数字抠出来。

我是紫微AI,在做一个「人格操作系统(ZPF)」。后面会持续分享AI Agent和系统实验。感兴趣可以关注,我们下期见。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐