【发布时间】:2019-12-21 12:40:59
【问题描述】:
我有一个昂贵的函数可以在许多并行的独立对象上执行,所以我正在尝试使用多处理模块。但是,内存消耗似乎处于失控的上升轨道上。请参阅下面的附图。
基本上我有一个大型二进制对象的路径列表。我有一个用这个列表实例化的类。在这个类的__iter__ 方法中,我从磁盘读取文件并生成它。这个想法是我遍历这个对象列表(它将文件读入内存)并执行一些昂贵的操作。下面是一些示例代码来模拟这一点。我正在使用np.random.rand(100,100) 来模拟将大文件读入内存,如果模拟昂贵函数中的矩阵,我只是索引 [0,0] 元素。
import numpy as np
from pathos.multiprocessing import ProcessingPool as Pool
from memory_profiler import profile
class MyClass:
def __init__(self, my_list):
self.name = 'foo'
self.my_list = my_list
def __iter__(self):
for item in self.my_list:
yield np.random.rand(100,100)
def expensive_function(foo):
foo[0,0]
my_list = range(100000)
myclass = MyClass(my_list)
iter(myclass) # should not return anything
p = Pool(processes=4, maxtasksperchild=50)
p.map(expensive_function, iter(myclass), chunksize=100)
问题可以在情节中看到。内存消耗似乎在不断攀升。我预计总内存消耗约为每个子进程消耗的 4 倍,但情况似乎并非如此。
是什么导致了这种失控的内存使用,我该如何解决?
【问题讨论】:
-
我认为最简单的修复方法就是传入一个
np.random.rand(100, 100)。因为所有子进程都会有一个副本,所以你不需要在主进程中也复制它。跨度> -
顺便说一句如何绘制这个情节?看起来不错。
-
@Sraw 这样做的含义是,当意图可能是使用不同的实现时,所有进程都使用相同的 100x100 元素的随机实现。但是我认为解决方案是在每个子进程而不是在父进程中生成这些元素,可选地使用共享内存数组(每个子进程 1 个)来最小化内存分配
-
@Michael 是的,你说得非常对 :) 如果可以从子进程构造数组,那将是最好的。
-
我是
pathos作者。请注意,使用close、join和clear将关闭池、释放进程并从池单例字典中删除池对象。如果您多次调用 map 函数,这有助于内存管理。
标签: python multiprocessing python-multiprocessing pathos