问题中限定语言是C++,可讨论的范围就比较精简了。现有的答案都在谈系统架构层次上的东西,略显跑题。我对C++了解不多,但我尝试以一名C++程序员的视角,从基本思路出发做一个分析,抛砖引玉。

首先我们要明确系统的需求。所谓交易系统,从一个应用程序的角度来说,有以下几个特点:

  1. 一定是一个网络相关的应用,假如机器没联网,肯定什么交易也干不了。所以系统需要通过TCP/IP连接来收发数据。数据要分两种,一种从交易所发过来的市场数据,流量很大,另一种是系统向交易所发出的交易指令,相比前者流量很小,这两种数据需要在不同的TCP/IP连接里传输。
  2. 因为是自动化交易系统,人工干预的部分肯定比较小,所以图形界面不是重点。而为了性能考虑,图形界面需要和后台分开部署在不同的机器上,通过网络交互,以免任何图形界面上的问题导致后台系统故障或者被抢占资源。这样又要在后台增加新的TCP/IP连接。
  3. 高频交易系统对延迟异常敏感,目前(2014)市面上的主流系统(可以直接买到的大众系统)延迟至少在100微秒级别,顶尖的系统(HFT专有)可以做到10微秒以下。其他答案里提到C++随便写写延迟做到几百微秒,是肯定不行的,这样的性能对于高频交易来说会是一场灾难。
  4. 系统只需要专注于处理自己收到的数据,不需要和其他机器合作,不需要担心流量过载。

有了以上几点基本的认识,我们可以看看用C++做为开发语言有哪些需要注意的。

首先前两点需求就决定了,这种系统一定是一个多线程程序。虽然对于图形界面来说,后台系统相当于一个服务端,但这部分的性能不是重点,用常用的模式就能解决。而重要的面向交易所那端,系统其实是一个客户端程序,只需要维护好固定数量的连接就可以了。为延迟考虑,一定要选择异步I/O(阻塞的同步I/O会消耗时间在上下文切换),这里有两点需要注意:

  • 是否可以在单线程内完成所有处理?考虑市场数据的流量远远高于发出的交易指令,在单线程内处理显然是不行的,否则可能收了一大堆数据还没开始处理,错过了发指令的最佳时机。
  • 有答案提到要压低平时的资源使用率,这是完全错误的设计思路。问题同样出在上下文切换上,一旦系统进入IDLE状态,再重新切换回处理模式是要付出时间代价的。正确的做法是保持对异步socket的疯狂轮询,一旦有消息就立刻处理,之后继续轮询,这样是最快的处理方式。(顺带一提现在的CPU一般会带有环保功能,使用率低了会导致CPU进入低功耗模式,同样对性能有严重影响。真正的低延迟系统一定是永远发烫的!)

现在我们知道核心的模块是一个多线程的,处理多个TCP/IP连接的模块,接下来就可以针对C++进行讨论。因为需要对接受到的每个TCP或UDP包进行处理,首先要考虑的是如何把包从接收线程传递给处理线程。我们知道C++是面向对象的语言,一般情况下最直观的思路是创建一个对象,然后发给处理线程,这样从逻辑上看是非常清晰的。但在追求低延迟的系统里不能这样做,因为对象是分配在堆上的,而堆的内存结构对我们来说是完全不透明的,没办法控制一个对象会具体分到内存的什么位置上,这直接导致的问题是本来连续收到的网络包,在内存里的分布是分散的,当处理线程需要读取数据时就会发生大量的cache miss,产生不可控的延迟。所以对C++开发者来说,第一条需要谨记的应该是,不要随便使用堆(用关键字new)。核心的数据要保证分配在连续内存里。

另一个问题在于,市场数据和交易指令都是结构化的,包含了股票名称,价格,时间等一系列信息。如果使用C++ class来对数据进行建模和封装,同样会产生不可知的内存结构。为了严格控制内存结构,应该使用struct来封装。一方面在对接收到的数据解析时可以直接定义名称,一方面在分配新对象(比如交易指令)时可以保证所有数据都分配在连续的内存区域。

以上两点是关于延迟方面最重要的注意事项。除此之外,需要考虑的是业务逻辑的编写。高频交易系统里注定了业务逻辑不会太复杂,但重要的是要保证正确性和避免指针错误。正确性应该可以借助于C++的特性比如强类型,模板等来加强验证,这方面我不熟悉就不多说了。高频系统往往运行时要处理大量订单,所以一定要保证系统运行时不能崩溃,一旦coredump后果很严重。这个问题也许可以多做编译期静态分析来加强,或者需要在系统外增加安全机制,这里不展开讨论了。

以下是几点引申思考:

  • 如何存储系统日志?
  • 如何对系统进行实时监控?
  • 如果系统coredump,事后如何分析找出问题所在?
  • 如何设计保证系统可用性,使得出现coredump之类的情况时可以及时切换到备用系统?

这些问题相信在C++框架内都有合适的解决方案,我对此了解不多,所以只列在这里供大家讨论。

— 完 —

本文作者:董可人

【知乎日报】
你都看到这啦,快来点我嘛 Σ(▼□▼メ)

此问题还有 9 个回答,查看全部。
延伸阅读:
为什么用 C 语言 sdk 而不用 C++ mfc 做这个系统?
初学 C 语言,Windows 7 系统下用什么 IDE 比较适合?

分享到