skynet lua 服务的内存管理优化
前两天一直困扰我的问题是并发启动 lua state 比串行启动它们要慢的多。而启动 lua state 的操作相互是完全无关的,没有任何应用层的锁。原本我以为多核同时做这些事情,即使不比单核快,也不至于慢一倍吧?
昨天有同学在 google talk 上和我讨论这个问题,说要不要考虑下是内存资源方面的问题。比如,在大量线程同时申请并读写大量内存时,有可能引起操作系统在映射物理内存到虚拟地址空间这个操作上出现性能问题。
虽然最后确认不是这个原因,但这启发我可能内存分配器在多核上工作并不顺畅。
我们使用 skynet 的项目利用 jemalloc 替换了默认 glibc 的分配器。tcmalloc 也应该是一个好的选择。但无论是哪个,都有多线程锁的问题。而 lua 可以自定义内存管理器,我们在 lua 服务启动时,若预分配 1M 内存,那么在这 1M 内存内的内存管理就完全没有线程安全的顾虑了,理论上这种定制的内存管理器会比一切通用管理器表现更好。
昨天我花了 3 个小时实现了一个简单的 lua 内存管理器,提交到 github 上。默认是关闭的,有兴趣使用的同学可以在 service_lua.c
里把
#define PREALLOCMEM (1024 * 1024)
的注释去掉。这样就可以启用为 skynet 专配的 lua 内存分配器了。
实测这个分配器会比 glibc 的版本好 40% 以上,比 jemalloc 好 5% 左右。它虽然依然不能解释多核并发初始化 lua state 反而更慢的问题,但本身还是对性能有不少改进的。
Comments
Posted by: 青岛珲莎舍 | (8) December 28, 2013 01:35 PM
Posted by: 晓锋 | (7) December 27, 2013 11:23 PM
Posted by: guest | (6) December 27, 2013 08:28 PM
Posted by: 程序员主页 | (5) December 27, 2013 12:24 AM
Posted by: mine260309 | (4) December 23, 2013 02:35 PM
Posted by: coollen.mmx | (3) December 21, 2013 11:34 AM
Posted by: heeroz | (2) December 20, 2013 10:55 PM
Posted by: lee | (1) December 20, 2013 10:21 PM