基于多核处理器的python粗粒度并行化

2024-06-16 12:43:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个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个核是真的(我在其他计算机/处理器中测试代码,我得到的结果相同,只有真正的内核似乎有用)。在


Tags: 代码in程序核心forfoo时间proc
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对子进程执行任何剩余的清理。然后让代码启动下一个子进程。在

相关问题 更多 >