c ++程序在不同的机器上显示非常不同的内存行为

时间:2013-10-15 16:28:24

标签: c++ multithreading memory c++11 libc

我用C ++编写了一个需要大量内存的计算机模拟。它在迭代中运行,并且在每次迭代中分配大量内存,这些内存应该在迭代结束时释放。它还使用c ++ 11的<thread>实现来并行运行东西。

当我在桌面计算机上测试程序时,它表现良好:它永远不会超过我允许的内存,在时间和迭代期间,没有任何内容堆积起来。但是,当我将程序提交给我们的计算集群时,所使用的内存(我只能通过排队软件访问)随着时间的推移而增长,并且远远超过了我的计算机上使用的内存。

让我首先向您展示软件的结构:

for thread in n_threads:
    vector<Object> container;
    for iteration in simulation:
        container.clear()
        container.resize(a_large_number)
        ... do stuff ...

让我们说,在我的机器上,容器会耗尽2GB内存。我可以在htopvalgrind --tool=massif中看到这些2GB永远不会被超越。没有什么可以堆积的。但是,在集群上,我可以看到内存增长和增长,直到它变得远远超过2GB(并且作业被终止/计算节点冻结......)。请注意,我限制了两台机器上的线程数量,并且可以确保它们是相同的。

我所知道的是,群集上的libc已经很老了。为了编译我的程序,我需要编译新版本的g++并更新集群前端节点上的libc。该软件在计算节点上运行良好(除了这个内存问题),但libc在那里更老了。这可能是一个问题,特别是与线程一起,用于内存分配?我怎么调查呢?

1 个答案:

答案 0 :(得分:1)

是的,根据GNU libc的年龄,您可能会遗漏一些重要的内存分配优化。以下是一些可以尝试的事情(不用说,冒着性能损失的风险):

  1. 您可以尝试通过mallopt()调整malloc / free行为;使用M_MMAP_MAXM_MMAP_THRESHOLD选项可以鼓励更多分配通过mmap(),这样可以保证在free()之后将内存返回给系统。

  2. 尝试将容器的分配器设为__gnu_cxx::malloc_allocator,以确保mallopt()调整影响容器。

  3. 请在调整大小后尝试调用container.shrink_to_fit(),以确保该向量不会扣留超出严格要求的内存。