我们开发了一个大型C ++应用程序,它在大型Linux和Solaris机箱上的多个站点上运行令人满意(最多160个CPU核心甚至更多)。它是一个高度多线程(1000+线程)的单进程架构,占用大量内存(200 GB +)。我们LD_PRELOADing谷歌Perftool的tcmalloc(或Solaris上的libumem / mtmalloc),以避免内存分配性能瓶颈,通常有良好的结果。但是,我们开始在一些较大的安装中看到内存分配/释放期间锁争用的不利影响,特别是在进程运行一段时间之后(这暗示了分配器的老化/碎片效应)。
我们正在考虑更改为多进程/共享内存架构(繁重的分配/解除分配不会发生在共享内存中,而是发生在常规堆上)。
所以,最后,我们的问题是:我们可以假设现代Linux内核的虚拟内存管理器能够有效地将内存分发给数百个可靠的进程吗?或者我们不得不期望遇到与我们在单进程/多线程环境中看到的内存分配争用相同的问题?我倾向于希望获得更好的整体系统性能,因为我们不再局限于单个地址空间,并且具有多个独立地址空间将需要较少的锁定虚拟内存管理器。任何人都有比较多线程和多进程内存分配的实际经验或性能数据吗?
答案 0 :(得分:1)
我倾向于希望获得更好的整体系统性能,因为我们不再局限于单个地址空间,并且具有多个独立地址空间将需要较少的锁定虚拟内存管理器。
没有理由期待这一点。除非您的代码设计得如此糟糕,以至于它不断回到操作系统来分配内存,否则它不会产生任何显着差异。您的应用程序只需要在需要更多虚拟内存时返回操作系统的虚拟内存管理器,一旦进程达到稳定大小,就不应该显着发生。
如果你不断地分配和释放一直回到操作系统,你应该停止这样做。如果您不这样做,那么您可以保留多个线程可以使用的多个已分配内存池而不会发生争用。而且,作为一种好处,您的上下文切换将更便宜,因为TLB不必刷新。
只有当您无法减少地址空间更改的频率时(例如,如果您必须映射和取消映射文件)或者您必须更改其他共享资源(如文件描述符),您应该查看多进程选项