小镇的夕阳|深度 | X-Engine的In-Memory读性能优化( 五 )


对X-Engine中的所有Subtable进行分表 , 特定的分表只能在被特定Core上执行的线程所访问到 , 避免Cache中出现同一数据的多个副本以及同一数据在不同core的cache间传输 。
小镇的夕阳|深度 | X-Engine的In-Memory读性能优化这样Per-core-level Shared-nothing的架构有如下优势:
CPU cache效率高:同一份数据只可能缓存在一个CPU core的L1/L2 cache中 , 也避免了实现cache一致性的开销 。 线程不会发生context switch而导致Cache失效 。
大大减少线程同步的开销:数据在前台线程间不共享 , 不需要锁或原子操作等进行线程间同步 , 例如Cache的锁竞争和pointer swizzling的swizzle/unswizzle以及内存回收都同时可以解决 。
目前该方法对只读性能的提升达到30%左右 。 此项优化工作还未完全完成 , 进一步的我们需要优化对热点Subtable的访问问题, 另一方面在事务引擎中 , 跨表访问是非常常见的 , 如果一个线程执行一个需要访问到多张表的事务 , 则如何调度该事务是一个很有挑战性的问题 。
实验验证测试环境64threads , 2Socket.L1-Cache:32KB Data Cache / 32KB Instruction CacheL2 Cache:256KBL3 Cache:32MBRAM:512GB , 使用numactl --interleave=all关闭NUMA
测试场景key 16Byte , value 8Byte , 32张表 , 每张表2000W条记录 , 写入数据之后下压到L1层 , 执行一轮预读预热到缓存中 , 然后执行readrandom测试 。
测试结果我们以X-Engine原始架构的随机读性能做baseline , 然后依次叠加上前述的优化手段 。
第一步增加了新的数据页编码方法以及数据页上的SIMD指令查找算法 , 获得了13.8%的性能提升 。
第二步 , 我们在代码中增加了PointSwizzling优化 , 性能提升相比BaseLine达到了90% 。 最后我们重构了X-Engine的执行框架 , 引入多核无共享执行架构 。
最终整体性能相对比BaseLine的提升达到了123%. 测试中也分析了这测试过程中CPU L1 Data Cache miss率的变化以及程序运行的IPC的变化 。
小镇的夕阳|深度 | X-Engine的In-Memory读性能优化【小镇的夕阳|深度 | X-Engine的In-Memory读性能优化】为了确定我们的优化手段在哪些路径上产生了最关键的作用 , 我们对每一步优化手段产生的性能提升进行了breakdown测试并制作了如下的表格. 从这里可以看出对性能提升最大的一步是对DataBlock的间接应用改Direct引用 , 考虑到DataBlock的数目较多 , 其原始实现中的Hash查找表比较大 , Cache效率较低 , 产生这样的效果在预期之中 。 而Index和ExentMeta对象相对数目较少(大概为DataBlock的1/128), 本身具有较好的查找效率 , 因此对性能的影响也较小 。


推荐阅读