2. 测试环境搭建:硬件选型与系统调优

做性能基准测试,最怕什么?

怕你测出来的数据,根本不是你系统的真实水平。

硬件没选对,操作系统没调优,时间不同步——这三件事但凡有一件没做好,你的测试结果就是一堆废纸。我见过太多团队,花了几十万买机器,跑出来的延迟数据却比隔壁用旧服务器还差。为什么?因为环境没搭对。

这一章,我们就来聊聊怎么把测试环境搭扎实。从硬件选型到内核调优,再到时间同步,每一步我都会把我在项目中踩过的坑、总结的经验讲清楚。

2.1 硬件选型:别让硬件拖了后腿

量化交易系统对硬件的要求,说白了就三个字:快、稳、准

快,是延迟要低;稳,是不能掉链子;准,是时间要精确。我们一个一个来看。

2.1.1 CPU:核心频率比核心数量更重要

很多人选CPU,第一反应是看核心数。16核、32核,听着就厉害。但做交易系统,尤其是高频交易,单核性能才是王道

为什么?因为交易系统的核心逻辑,往往是单线程的。你想想看,行情数据来了,你得按顺序处理,不能并行。多核的优势主要体现在并发处理多个策略或回测任务上。

我个人习惯,选CPU时优先看这几个指标:

  • 主频:越高越好,建议4.0GHz以上。我见过有人用3.0GHz的CPU跑高频策略,结果行情波动一大,处理不过来,直接丢包。
  • 睿频:单核睿频能力要强。有些CPU全核跑不高,但单核能冲到5.0GHz以上,这种就很适合。
  • 缓存:L3缓存越大越好。缓存命中率高,能减少内存访问延迟。
  • NUMA架构:多路服务器要注意NUMA节点。跨节点访问内存,延迟会高不少。
我的经验:如果你做的是高频交易,建议选Intel的Xeon W系列或AMD的Ryzen Threadripper Pro系列。这些CPU的单核性能强,而且支持AVX-512指令集,对某些数学运算有帮助。

2.1.2 内存:容量够用就行,频率和时序是关键

内存这块,很多人容易走极端。要么买超大容量,要么买最便宜的。

其实,对于交易系统来说,内存的频率时序比容量更重要。为什么?因为行情数据要频繁读写,内存延迟直接影响处理速度。

我建议的配置:

参数 推荐值 说明
容量 64GB - 128GB 够用就行,太多也用不上
频率 DDR4-3200 或更高 频率越高,带宽越大
时序 CL14 或更低 时序越低,延迟越小
通道 双通道或四通道 通道越多,带宽越高
注意:不要混插不同频率或时序的内存条。系统会以最低的那条为准,白白浪费性能。我曾经吃过这个亏,买了两条3200MHz和两条2666MHz的条子,结果全跑在2666上。

2.1.3 网卡:别用板载网卡做交易

这一点,我怎么说都不为过。板载网卡是给办公用的,不是给交易用的

板载网卡的问题在于:

  • CPU占用高:数据包处理全靠CPU,拖累主业务
  • 延迟不稳定:受系统中断影响大,延迟抖动明显
  • 功能有限:不支持硬件时间戳、RSS等高级功能

我建议用SolarflareMellanox的网卡。这些网卡支持:

  • 硬件时间戳:精确到纳秒级,对时间同步至关重要
  • RSS(接收端缩放):多队列并行处理,降低CPU负载
  • DPDK:用户态驱动,绕过内核协议栈,延迟极低
避坑指南:我曾经用一块Intel X710网卡做测试,结果发现延迟抖动很大。后来换成Solarflare SFN8522,延迟直接降了40%。网卡的钱,真不能省。

2.2 操作系统调优:把系统的潜力榨出来

硬件选好了,操作系统也得调。默认配置是给通用场景用的,不是给低延迟交易用的。

2.2.1 内核参数调优

Linux内核有很多参数可以调。我挑几个最关键的:

# 网络相关
net.core.rmem_max = 134217728      # 接收缓冲区最大大小
net.core.wmem_max = 134217728      # 发送缓冲区最大大小
net.core.netdev_budget = 600       # 每次轮询处理的数据包数量
net.core.netdev_budget_usecs = 1000 # 轮询时间上限(微秒)

# 中断相关
kernel.sched_migration_cost_ns = 5000000  # 进程迁移成本
kernel.sched_autogroup_enabled = 0        # 关闭自动分组

# 内存相关
vm.swappiness = 10                 # 尽量少用swap
vm.dirty_ratio = 5                 # 脏页比例上限
vm.dirty_background_ratio = 2      # 后台脏页比例

这些参数怎么来的?不是拍脑袋想的。我一般会先用sysctl -a看当前值,然后根据业务场景逐步调整。每次改完,跑一遍基准测试,看延迟和吞吐量的变化。

核心思路:减少中断、减少上下文切换、减少内存拷贝。所有调优都围绕这三点展开。

2.2.2 中断绑定:把网卡中断固定到特定CPU核心

默认情况下,网卡中断会在所有CPU核心之间轮转。这会导致一个问题:CPU缓存频繁失效,延迟不稳定。

解决办法是中断绑定。把网卡中断固定到某个或某几个CPU核心上,其他核心专心处理业务逻辑。

具体做法:

  1. 查看网卡中断号:cat /proc/interrupts | grep eth0
  2. 查看CPU核心编号:lscpu
  3. 绑定中断到指定核心:echo "2" > /proc/irq/123/smp_affinity(2表示CPU核心1)

嗯,这里要注意:smp_affinity的值是十六进制掩码。比如你想绑定到CPU核心0和核心2,掩码就是0x5(二进制0101)。

我的习惯:我会把网卡中断绑定到CPU核心0和1,业务逻辑跑在核心2-7上。这样中断处理和业务处理互不干扰。

2.2.3 其他调优技巧

  • 关闭CPU节能:在BIOS中关闭C-States和P-States,避免CPU频率波动。
  • 关闭超线程:超线程虽然能提高吞吐量,但会引入延迟不确定性。做低延迟交易,建议关闭。
  • 使用isolcpus:在内核启动参数中隔离特定CPU核心,不让系统调度普通进程到这些核心上。
# 在GRUB配置中添加
isolcpus=2,3,4,5,6,7 nohz_full=2,3,4,5,6,7 rcu_nocbs=2,3,4,5,6,7

2.3 时间同步:差一毫秒,可能亏一套房

时间同步,是量化交易系统里最容易忽视、但后果最严重的问题。

你想想看,如果你的系统时间比交易所慢了1毫秒,你看到的行情就是过时的。你下的单,可能比别人晚了一辈子。

2.3.1 NTP vs PTP:怎么选?

特性 NTP PTP
精度 毫秒级(1-10ms) 微秒级(<1μs)
硬件要求 低,普通网卡即可 高,需要支持PTP的网卡和交换机
适用场景 回测、中低频交易 高频交易、行情数据对齐
配置复杂度 简单 中等

我的建议是:能做PTP就做PTP,做不了再用NTP

为什么?因为NTP的精度受网络延迟影响太大。你测出来是1ms的误差,实际可能到10ms。而PTP利用硬件时间戳,精度可以到100纳秒以内。

2.3.2 PTP配置实战

以Linux系统为例,使用ptp4lphc2sys

# 安装工具
apt-get install linuxptp

# 配置ptp4l(/etc/linuxptp/ptp4l.conf)
[global]
network_transport      L2
delay_mechanism        P2P
time_stamping          hardware
tx_timestamp_timeout   10
logSyncInterval        0
logAnnounceInterval    1
logMinDelayReqInterval 0

# 启动PTP从时钟
ptp4l -f /etc/linuxptp/ptp4l.conf -i eth0 -m

# 同步系统时钟到PTP硬件时钟
phc2sys -s eth0 -c CLOCK_REALTIME -m -O 0
重要提醒:PTP依赖网络基础设施。你的交换机必须支持PTP(IEEE 1588v2),并且配置为边界时钟或透明时钟。否则,PTP的精度会大打折扣。

2.3.3 验证时间同步精度

配置完了,怎么知道准不准?

pmc工具查看:

# 查看PTP状态
pmc -u -b 0 'GET CURRENT_DATA_SET'
pmc -u -b 0 'GET TIME_STATUS_NP'

或者用chronyc(如果用的是NTP):

chronyc tracking
chronyc sources -v

我一般会连续监控24小时,看时间偏差的均值和标准差。如果偏差超过10微秒,就得排查问题了。

2.4 本章小结

测试环境搭建,说白了就是三件事:

  • 硬件:选对CPU、内存、网卡,别让硬件成为瓶颈
  • 系统:调优内核参数、绑定中断、隔离核心,把系统潜力榨出来
  • 时间:用PTP做高精度时间同步,确保数据对齐

这三件事做好了,你的基准测试结果才有参考价值。否则,你测出来的不是系统的性能,而是环境的混乱程度。

下一章,我们会聊测试工具的选择和基准测试脚本的编写。到时候,我会分享一些我自己写的测试脚本,以及怎么避免常见的测试陷阱。


专注资料整理