小编Rob*_*ley的帖子

产生python多处理池时出现意外的内存占用差异

试图为pystruct模块中的并行化做出贡献,并在讨论中试图解释我为什么要尽可能早地在执行中实例化池并尽可能长时间地保留它们,重用它们,我意识到我知道它最适合这样做,但我不完全知道为什么.

我知道*nix系统上的声明是池工作器子进程在写入时从父进程中的所有全局变量复制.总的来说情况确实如此,但我认为应该补充说,当其中一个全局变量是一个特别密集的数据结构,如numpy或scipy矩阵时,似乎任何引用都被复制到工作者中实际上是漂亮的即使整个对象没有被复制也是相当大的,因此在执行后期产生新池会导致内存问题.我发现最好的做法是尽早产生一个池,这样任何数据结构都很小.

我已经知道了一段时间并在工作中的应用程序中围绕它进行了设计,但我得到的最好的解释是我在帖子中发布的内容:

https://github.com/pystruct/pystruct/pull/129#issuecomment-68898032

从下面的python脚本看,基本上,你会期望第一次运行中创建的池中的空闲内存和第二次运行中创建的矩阵步骤基本相同,就像在最终池终止的调用中一样.但是它们从来都不是,当你首先创建池时,总会有(除非机器上还有其它东西)更多的空闲内存.在创建池时,这种影响会随着全局命名空间中数据结构的复杂性(和大小)而增加(我认为).有没有人对此有一个很好的解释?

我用bash循环和下面的R脚本来制作这个小图片来说明,在创建池和矩阵之后显示整体的可用内存,具体取决于顺序:

自由记忆趋势情节,两种方式

pool_memory_test.py:

import numpy as np
import multiprocessing as mp
import logging

def memory():
    """
    Get node total memory and memory usage
    """
    with open('/proc/meminfo', 'r') as mem:
        ret = {}
        tmp = 0
        for i in mem:
            sline = i.split()
            if str(sline[0]) == 'MemTotal:':
                ret['total'] = int(sline[1])
            elif str(sline[0]) in ('MemFree:', 'Buffers:', 'Cached:'):
                tmp += int(sline[1])
        ret['free'] = tmp
        ret['used'] = int(ret['total']) - int(ret['free'])
    return ret

if __name__ == '__main__':
    import argparse
    parser = …
Run Code Online (Sandbox Code Playgroud)

python numpy python-multiprocessing

12
推荐指数
1
解决办法
706
查看次数

标签 统计

numpy ×1

python ×1

python-multiprocessing ×1