【问题标题】:Multiprocessing Pool.apply executing n-1 timesMultiprocessing Pool.apply 执行 n-1 次
【发布时间】:2019-01-31 18:49:48
【问题描述】:

我遇到了multiprocessing.Pool.apply 的问题。
我的目标是有 5 个进程,每个进程用 100 个元素填充一个数组(此测试为 100 个),然后将数组合并成一个长度为 500 的数组。问题是,由于任何原因,它最终只有 400 个元素我不能明白。

我已尝试更改池创建的进程数量,但除了执行时间之外没有任何改变。

import torch.multiprocessing as mp
import itertools

pool = mp.Pool(processes=5)
split = int(500/5)
lst =  pool.apply(RampedGraph, (split,[]))    #each foo returns a list of 100 elements
lst = list(itertools.chain.from_iterable(lst)) #merging the lists into one

len(lst)
>>>400

len(lst) 的预期输出应该是500
谁能告诉我我做错了什么?

EDIT Foo 方法说明:

def RampedGraph(popsize, graph_lst):
    cyclic_size = int(math.ceil(popsize/2))
    acyclic_size = popsize - full_size
    append = graph_lst.append
    for _ in range(cyclic_size):
        t = c.Node().cyclic()
        nn = c.number_of_nodes()
        c = c.calculate(0, False)
        append((t,nn,c))
    for _ in range(acyclic_size):
        t = c.Node().acyclic()
        nn = c.number_of_nodes()
        c = c.calculate(0, False)
        append((t,nn,c))
    return graph_lst

【问题讨论】:

  • @unutbu done ,添加完整方法
  • pool.apply(RampedGraph, (split,[])) 只调用一次RampedGraph(split, [])。您是否尝试拨打RampedGraph 5 次?都是同一个论点?
  • @unutbu 我试图为每个进程调用一次,所以我可以合并 5 个 100 个元素的数组。都具有相同的论点

标签: python python-3.x multiprocessing pool


【解决方案1】:
import torch.multiprocessing as mp
# import multiprocessing as mp
import itertools

def RampedGraph(popsize, graph_lst):
    print(mp.current_process().name)
    return list(range(100))

num_workers = 5
pool = mp.Pool(processes=num_workers)
split = int(500/num_workers)
lst =  pool.starmap(RampedGraph, [(split,[])]*num_workers)
lst = list(itertools.chain.from_iterable(lst)) 
print(len(lst))
# 500

pool.starmap(RampedGraph, [(split,[])]*5) 向任务池发送 5 个任务。 它导致RampedGraph(split, []) 被同时调用 5 次。 RampedGraph 返回的 5 个结果被收集到一个列表中,lst

请注意,同时调用RampedGraph 5 次并不能保证使用所有 5 个处理器。例如,如果RampedGraph 非常快地完成,则一个处理器可能处理多个任务,并且可能根本不会使用另一个处理器。 但是,如果RampedGraph 花费大量时间,通常您可以预期会使用所有 5 个工作进程。

注意:我使用import multiprocessing as mp 而不是import torch.multiprocessing as mp 运行上述代码。但是由于torch.multiprocessing 应该是multiprocessing 的替代品,所以这应该没什么区别。


使用multiprocessing 会带来成本和收益。 当然,好处是能够同时使用多个处理器。 成本包括启动额外进程所需的时间,以及进程间通信的成本。 multiprocessing 使用 Queues 将参数传输到工作进程运行的函数,并将返回值传输回主进程。为了通过队列传输返回值,对象通过酸洗序列化为字节。如果通过队列发送的腌制对象很大,则在使用多处理时会增加显着的开销成本。请注意,所有这些成本都不是由相同代码的等效顺序版本产生的。

特别是当工作进程运行的函数快速完成时,开销成本可能会主导程序的总运行时间,使得使用多处理的代码比相同代码的顺序版本慢。

因此,使用多处理时提高速度的关键是尽量减少进程间通信,并确保工作进程完成大量工作,从而使开销成本在总运行时间中占相对较小的一部分。

【讨论】:

  • 非常感谢!
  • 哼。知道为什么这种方法的执行时间比简单地用 500 个元素填充数组要多 3 倍吗?我假设它会减少执行时间,而不是三倍:/
  • 我添加了几句话,说明为什么 multiprocessing 有时会比相同代码的顺序版本慢。我不知道它是否适用于你的情况。我们可能需要查看您的实际可运行代码才能进行调查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-17
  • 1970-01-01
  • 2022-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多