【发布时间】:2020-05-01 00:09:28
【问题描述】:
我已经针对较大对象的一些问题实现了多处理,如下所示:
import time
import pathos.multiprocessing as mp
from functools import partial
from random import randrange
class RandomNumber():
def __init__(self, object_size=100):
self.size = bytearray(object_size*10**6) # 100 MB size
self.foo = None
def do_something(self, *args, **kwargs):
self.foo = randrange(1, 10)
time.sleep(0.5) # wait for 0.5 seconds
return self
def wrapper(random_number, *args, **kwargs):
return random_number.do_something(*args, **kwargs)
if __name__ == '__main__':
# create data
numbers = [RandomNumber() for m in range(0, 9)]
kwds = {'add': randrange(1, 10)}
# calculate
pool = mp.Pool(processes=mp.cpu_count())
result = pool.map_async(partial(wrapper, **kwds), numbers)
try:
result = result.get()
except:
pass
# print result
my_results = [i.foo for i in result]
print(my_results)
pool.close()
pool.join()
产生类似的东西:
[8, 7, 8, 3, 1, 2, 6, 4, 8]
现在的问题是,当对象非常小时,与使用列表推导相比,我在性能上有了巨大的改进,而这种改进在更大的对象大小时变成了相反的情况,例如100 MB 或更大。
从documentation 和其他问题中,我发现这是由于使用 pickle/dill 对单个对象进行序列化以便将它们传递给池中的工作人员造成的。换句话说:对象被复制,这个 IO 操作成为瓶颈,因为它比实际计算更耗时。
我已经尝试使用multiprocessing.Manager 处理同一个对象,但这会导致运行时间更长。
问题是我被绑定到一个特定的类结构(这里通过RandomNumber() 表示),我无法改变它..
现在我的问题是:是否有任何方法或概念来规避这种行为,并且只在do_something() 上调用我,而无需序列化或复制的开销?
欢迎任何提示。提前致谢!
【问题讨论】:
-
这是否涉及 IO 或 CPU 密集型任务
-
这是一个占用大量 CPU 资源的任务。我将数学求解器应用于特定问题,而数据负责对象的内存大小。
标签: python python-multiprocessing pathos