【问题标题】:Why is get() slow in multiprocessing?为什么 get() 在多处理中很慢?
【发布时间】:2015-01-16 01:07:11
【问题描述】:

我有一个基本的多处理类,它接受一些参数并将它们发送给工作人员:

class Multi(object):
    def __init__(self, pool_parameters, pool_size):
        self.pool_parameters = pool_parameters  # Parameters in a tuple
        self.pool_size = pool_size
        self.pool = mp.Pool(self.pool_size)
        self.results = \
            [self.pool.apply_async(worker, args=((self.pool_parameters[i]),),)
                for i in range(self.pool_size)]
        time1 = time.time()
        self.output = [r.get() for r in self.results]  # Output objects in here
        print time.time() - time1

def worker(*args):
    # Do stuff
    return stuff

但是 r.get() 行似乎需要很长时间。如果我的 pool_size 为 1,则工作人员会在 0.1 秒内返回其结果,但 r.get() 行又需要 1.35 秒。为什么需要这么长时间,尤其是如果只启动一个进程?

编辑:对于单个进程并使用 worker 返回单个 None 值,self.output 行在我的系统上仍然需要 1.3 秒(使用 time.time() 来计时该行)

EDIT2:抱歉,我发现了问题,我认为这与多处理无关。问题似乎来自导入各种其他模块。当我摆脱进口时,时间是 0.1 秒。不知道为什么...

【问题讨论】:

  • 您从worker 返回的对象有多大?另外,您如何测量运行get 调用需要多长时间?
  • 它包装了一个图像文件和一个 csv 文件,所以它目前大约 8 mb。但最终它应该是 250 mb。我在 self.output 行的任一侧使用 time.time() 。在类外调用worker()是0.1秒

标签: python multiprocessing


【解决方案1】:

您发现性能很差,因为您在进程之间发送了一个大对象。在子进程中酸洗对象,在进程之间发送这些字节,然后在父进程中解开它们,需要大量的时间。这是multiprocessing 的最佳实践建议avoiding large amounts of shared state 的原因之一:

避免共享状态

应尽量避免大量转移 进程之间的数据。

如果您在对象上调用pickle.loads(pickle.dumps(obj)),您可能能够隔离此行为。我希望它花费的时间几乎与get() 通话一样长。

【讨论】:

  • 啊哈对象被腌制了,这是有道理的!如果我删除包含对图像文件的引用的对象部分,那么这应该加快速度吗?
  • @kezzos 是的,worker 的返回值越小,get 应该越快。
  • 从工作人员返回“无”仍然会导致 get() 调用需要 1.3 秒。这是使用多处理的开销吗?
  • @kezzos 你是怎么衡量的?你能提供一个完整的例子吗?我不能说我以前从未注意到过这么多开销。
  • 您应该将此与不使用多处理所需的时间进行比较。
猜你喜欢
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
  • 2015-01-29
  • 2013-10-05
  • 2012-06-01
  • 2018-06-11
  • 1970-01-01
相关资源
最近更新 更多