我有一个python程序,在某种程度上它调用一个外部程序(foo)。这个外部程序需要运行几次。准确的次数(num_pros)是可变的,取决于输入。 因为这个外部程序是Python程序中最耗时的部分,所以我想利用多核处理器同时运行外部程序的几个实例。在
我提出了以下解决方案,考虑到num_pros是先验未知的,并且该解决方案应该适用于任何数量的核心。在
cores=2
proc_list=[]
for i in range(0,num_pros):
proc=Popen(['foo'], stdin=PIPE)
proc_list.append(proc)
if i%cores == cores-1:
for process in proc_list:
process.wait()
我有两个问题:
有更好的(更有效的还是Python式的)解决方案?在
这段代码只在核心是真实的情况下才减少执行时间。这是硬件问题吗?或者可以用python修复的东西?在
为了澄清第二个问题,让我举个例子。 在我的笔记本电脑(运行linux)中,命令“cat/proc/cpuinfo | grep processor | wc-l”表示存在4个处理器,如果我在代码中使用cores=2,我会在一半的时间内得到结果(如预期的那样),但是当使用cores=3或cores=4时,我得到的性能与使用cores=2时的性能相同。我有一个英特尔酷睿I3(2核和4线程),因此我猜问题是只有2个核是真的(我在其他计算机/处理器中测试代码,我得到的结果相同,只有真正的内核似乎有用)。在
简单的方法:采用一个N核系统,进行一些基准测试,以确定你的应用程序需要执行多少个进程才能达到最高效率。它可能是N、N+1或N+2个过程(例如,对于通常的软件构建
make
运行,文档通常建议将-j设置为N+1)。然后对于生产运行,只需向用户或操作系统询问物理内核的数量(不是线程),然后生成N个或N+1个或任何进程。在更复杂、更酷,也不一定是更好的方法:如果您可以测量已完成的工作单元的吞吐量,那么您可以尝试在不知道/检测cpu/核心/线程数量的情况下动态调整进程的数量-如果您愿意,可以类似于TCP窗口大小。从2个进程的目标开始,当第一个进程结束时,测量吞吐量并转到target+=1(即,使总数达到3个进程)。测量,冲洗,重复。只要总吞吐量继续上升,就保持递增;当总吞吐量下降时,就降低吞吐量。在混合中加入一些滞后性,确保配置一个合理的上限。在
关于你的笔记本电脑的例子,是的,这是一个多线程的CPU,多线程将比其他线程更有益于某些工作负载,你的是一个没有从中受益的:)
我认为
multiprocessing
更适合于您希望外包的工作是在python中完成的,而不是完全不同的过程。这一切都是关于使用fork
并将内容从python进程传递到python进程,所以我认为它不适合您。在在当前的实现中,一旦生成了最大数量的子进程,您的代码将阻止新子进程的生成,直到当前的一批进程完成为止,因为
Popen.wait()
将阻塞,直到特定的子进程完成。在我想你想要的是^{} 。我做了一件very similar的事情,通过保持由pid映射的
subprocess.Popen
实例的映射。只需启动最大数量的子进程,然后让os.wait()
告诉您其中一个进程何时完成。os.wait()
将为您提供Popen
实例下一步完成的任何pid,您可以使用该pid对该子进程执行任何剩余的清理。然后让代码启动下一个子进程。在相关问题 更多 >
编程相关推荐