【研究报告】功夫共享内存通信开销分析

xinze/核心开发

背景:

在tick-to-order延迟测试过程中,采用提高编译时SPDLOG级别以减少运行时开销,并将各进程绑定在专属CPU核心上避免运行过程中切换核心带来的cache miss这两种有效步骤之后,延迟表现有所提升。但一笔订单记录从策略进程写完到td读到仍需要2us左右的时间开销,与模拟单写单读进程共享内存通信测试结果有差异,进一步分析探索高开销步骤位置以及是否有优化空间。

测试过程:

在12核心3.40GHz的机器32上,分别探索了读、写过程的时间构成,采用系统外模拟与功夫系统内魔改方式获取、分析高开销步骤,验证优化效果。

测试结论:
写操作中的各步骤及开销: 

写开销实际表现符合预期。

读操作中的各步骤及开销:

读开销步骤1-4之和为2us左右,与之前tick-to-order延迟测试过程中一笔订单记录从策略进程写完到td读到开销一致。优化步骤2之后读开销可优化600ns左右。

现象解释

1 当使用大页内存的情况下进行共享内存通信延迟测试时,也不可避免会产生内存碎片,因此随着测试次数的增加,mmap时可用的完整连续内存将减少,进而会导致整体测试结果开销有所增加。

2 同一场景多次测试过程中,会发现通信开销表现在一个范围内波动,而不是一个固定值,这是因为跨核心进行共享内存通信时涉及到缓存一致性问题,通常由硬件和底层系统实现的MESI协议等来管理cache line的一致性,在软件层面上并没有直接的控制接口,因此无法直接干预。

3 在测试结果中,写开销往往小于读开销,与通常印象中写开销大于读开销不同,这里主要有两方面原因:缓存一致性协议会对写操作的开销进行优化,通过预设的缓存策略和写回机制,减少对其他缓存和主存的写操作,提高整体性能;同时由于是跨CPU核心进行共享内存通信,写进程的写操作更新的不是读进程的本地缓存,读进程的本地缓存失效后需要从其他缓存或主存加载最新的数据,想比较于同一核心读写引入了更多传输和通信开销。