Python 多处理池.apply执行n-1次
我对Python 多处理池.apply执行n-1次,python,python-3.x,multiprocessing,pool,Python,Python 3.x,Multiprocessing,Pool,我对多处理.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有问题
我的目标是有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
有人能告诉我我做错了什么吗
编辑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
将5个任务发送到任务池。
它导致同时调用RampedGraph(split,[])
。
RampedGraph
返回的5个结果被收集到一个列表中,lst
请注意,同时调用RampedGraph
5次并不保证使用所有5个处理器。例如,如果RampedGraph
完成得非常快,则一个处理器可能处理多个任务,而另一个处理器可能根本就不会被使用。
但是,如果RampedGraph
花费了大量时间,通常您可以期望使用所有5个工作进程
注意:我使用import multiprocessing as mp
运行上述代码,而不是import torch.multiprocessing as mp
。但既然torch.multi-processing
被认为是multi-processing
的替代品,那就没什么区别了
使用多处理
既有成本,也有好处。
当然,好处是能够同时使用多个处理器。
成本包括启动额外进程所需的时间,以及进程间通信的成本<代码>多处理
使用队列
将参数传输到工作进程运行的函数,并将返回值传输回主进程。为了通过队列传输返回的值,通过pickle将对象序列化为字节。如果通过队列发送的pickle对象很大,则在使用多处理时会增加大量开销。请注意,所有这些成本都不是由相同代码的等效顺序版本引起的
特别是当辅助进程运行的函数很快完成时,开销成本可能会支配程序的总运行时间,使使用多处理的代码比相同代码的顺序版本慢
因此,在使用多处理时,提高速度的一个关键是尽量减少进程间通信,并确保工作进程做大量工作,这样开销成本就只占总运行时间的一小部分。@unutbu done,添加了完整的方法pool.apply(RampedGraph,(split,[])
仅调用RampedGraph(拆分,[])
一次。你想调用RampedGraph
五次吗?都使用相同的参数?@unutbu我试图为每个进程调用一次,这样我就可以合并5个包含100个元素的数组。都使用相同的参数。非常感谢!哼。你知道为什么这种方法比简单地用500个e填充数组要多花3倍的时间来执行吗元素?我认为它会缩短执行时间,而不是将执行时间增加三倍:/我补充了几句话,解释了为什么多处理
有时会比同一代码的顺序版本慢。我不知道它是否适用于您的情况。我们可能需要查看您的实际可运行代码才能进行调查。
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