繁体   English   中英

Pool / starmap的Python多处理行为

[英]Python multiprocessing behavior of Pool / starmap

我有一个使用多处理库来计算一些东西的程序。 大约有1万个输入要计算,每个输入需要0.2秒至10秒。

我当前的方法使用池:

# Inputs
signals = [list(s) for s in itertools.combinations_with_replacement(possible_inputs, 3)]

# Compute
with mp.Pool(processes = N) as p:
    p.starmap(compute_solutions, [(s, t0, tf, folder) for s in signals])
    print ("    | Computation done.")

我注意到,在检查300/400个最后输入时,该程序变慢了很多。 我的问题是: Poolstarmap()行为如何?

通过观察,我相信如果我得到1万个输入并且N = 4 (4个进程),则将2 500个第一个输入分配给第一个进程,将2 500个分配给第二个进程,...每个进程都将其视为以串行方式输入。 这意味着,如果某些进程先于其他进程清除了队列,则它们不会获得要执行的新任务。

这个对吗?

如果这是正确的,我如何拥有一个可以用此伪代码表示的更智能的系统:

workers = Initialize N workers
tasks = A list of the tasks to perform

for task in tasks:
    if a worker is free:
        submit task to this worker
    else:
        wait

谢谢您的帮助 :)

注意:不同的地图功能之间有什么区别。 我相信map()imap_unordered()imapstarmap存在。

它们之间有什么区别,什么时候应该使用另一个?

这意味着,如果某些进程先于其他进程清除了队列,则它们不会获得要执行的新任务。

这个对吗?

multiprocess.Pool()的主要目的是将传递的工作负载分散到其工作池中,这就是为什么它带有所有这些映射选项的原因-各种方法之间的唯一区别在于工作负载的实际分配方式和如何收集所得收益。

在您的情况下,使用[(s, t0, tf, folder) for s in signals]生成的可迭代对象[(s, t0, tf, folder) for s in signals]每个元素(最终取决于signals大小)将发送到下一个空闲工作程序(调用为compute_solutions(s, t0, tf, folder) ),一次(如果传递了chunksize参数,则一次),直到整个可迭代耗尽为止。 您无法控制哪个工作人员执行哪个部分。

工作负载也可能分布不均-根据资源使用情况,执行速度,各种内部事件,一个工作人员可能比另一个工作人员处理更多的条目...

但是,使用mapimapstarmap方法进行multiprocessing.Pool starmap会产生均匀有序分布的错觉,因为它们内部同步每个工作人员的返回值以匹配可迭代的 (即结果的第一个元素将包含结果从被调用函数的返回与iterable的第一个元素)。 如果您想查看实际发生的情况可以尝试使用这些方法的异步/无序版本。

因此,默认情况下您将获得更智能的系统 ,但是如果您希望对工作人员池进行完全控制,则可以始终使用multiprocessing.Pool.apply_async()

附带说明一下,如果您想优化对可迭代对象本身的访问(因为池映射选项将消耗其中的很大一部分),则可以查看此答案

最后,

它们之间有什么区别,什么时候应该使用另一个?

与其在这里引用我,不如直接去查阅官方文档,因为它们之间有很大的区别。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM