2

我们开发了一个大型 C++ 应用程序,它可以在大型 Linux 和 Solaris 机器上的多个站点上令人满意地运行(多达 160 个 CPU 内核甚至更多)。这是一个高度多线程(1000+ 线程)、单进程架构,消耗大量内存(200 GB+)。我们正在对 Google Perftool 的 tcmalloc(或 Solaris 上的 libumem/mtmalloc)进行 LD_PRELOAD 处理,以避免内存分配性能瓶颈,通常效果良好。但是,我们开始看到内存分配/释放期间锁争用对一些较大的安装的不利影响,尤其是在进程运行了一段时间之后(这暗示了分配器的老化/碎片效应)。

我们正在考虑更改为多进程/共享内存架构(重分配/释放不会发生在共享内存中,而是在常规堆上)。

所以,最后,这是我们的问题:我们能否假设现代 Linux 内核的虚拟内存管理器能够有效地将内存分配给数百个并发进程?或者我们是否必须预期会遇到与我们在单进程/多线程环境中看到的相同类型的内存分配争用问题?我倾向于希望获得更好的整体系统性能,因为我们将不再局限于单个地址空间,并且拥有多个独立地址空间将需要更少的虚拟内存管理器锁定。有人有比较多线程与多进程内存分配的实际经验或性能数据吗?

4

1 回答 1

1

我倾向于希望获得更好的整体系统性能,因为我们将不再局限于单个地址空间,并且拥有多个独立地址空间将需要更少的虚拟内存管理器锁定。

没有理由期待这一点。除非您的代码设计得如此糟糕以至于它不断返回操作系统来分配内存,否则它不会产生任何显着差异。您的应用程序应该只在需要更多虚拟内存时才需要返回到操作系统的虚拟内存管理器,一旦进程达到其稳定大小,这种情况不会显着发生。

如果您一直在一直分配和释放到操作系统,您应该停止这样做。如果不是,那么您可以保留多个已分配内存池,供多个线程使用而不会发生争用。而且,作为一个好处,您的上下文切换会更便宜,因为不必刷新 TLB。

只有当您不能减少地址空间更改的频率(例如,如果您必须映射和取消映射文件)或如果您必须更改其他共享资源(如文件描述符)时,您才应该查看多进程选项。

于 2016-09-15T11:17:21.730 回答