我有一个要与multiprocessing
库并行化的进程。每个进程都做一些事情,但是每个进程要做的一件事就是调用一个运行优化的函数。现在,每次优化的90%的时间将在不到1分钟的时间内完成,但是如果没有完成,它可能永远不会收敛。有一个内部机制可以终止优化函数,如果该函数在经过20,000次迭代后仍未收敛,则可能会花费很长时间(〜1小时)。
现在我的代码看起来像这样:
pool = multiprocessing.Pool()
imap_it = pool.imap_unordered(synth_worker, arg_tuples)
while 1:
try:
result = imap_it.next(timeout=120)
process_result(result)
except StopIteration:
break
except multiprocessing.TimeoutError:
pass
pool.close()
pool.join()
这似乎效果很好,因为我能够相当快地处理前90%的结果,但是到最后,较长的过程开始陷入困境,每10分钟只有一个过程完成。奇怪的是,一旦到达这一点,并且我在终端上运行top
,即使我的Pool中有24个CPU,似乎只有5-6个并行进程正在运行。我还看到运行开始时所有24个CPU都在使用。同时,我看到还有100多个尚未完成(甚至开始)的任务。我没有使用imap_unordered
的任何内置分块选项,因此我的理解是,只要一个进程完成,运行完成的进程的工作人员就应该选择一个新的。为什么要运行的并行进程少于剩余任务,除非所有剩余任务都已分配给等待非收敛性优化达到20,000个迭代截止时间的5-6个阻塞的工作人员?有任何想法吗?我应该尝试另一种方法来遍历Pool传入的结果吗?
运行here开始时top
的输出
top
的输出,一旦作业似乎卡住了here
和this是作业开始卡住时的标准输出。