Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用多核处理器的python粗粒度并行化_Python_Multithreading_Parallel Processing_Multicore - Fatal编程技术网

使用多核处理器的python粗粒度并行化

使用多核处理器的python粗粒度并行化,python,multithreading,parallel-processing,multicore,Python,Multithreading,Parallel Processing,Multicore,我有一个python程序,它在某一点上调用一个外部程序(foo)。这个外部程序需要运行几次。确切的次数(num_pros)是可变的,取决于输入。 因为这个外部程序是Python程序中最耗时的部分,所以我想利用多核处理器同时运行外部程序的多个实例 我提出了以下解决方案,考虑到num_pros是先验未知的,并且该解决方案应该适用于任意数量的内核 cores=2 proc_list=[] for i in range(0,num_pros): proc=Popen(['foo'], stdin

我有一个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修复的东西

为了澄清第二个问题,让我举一个例子。
在我的笔记本(运行linux)中,comnand'cat/proc/cpuinfo | grep processor | wc-l'表示存在4个处理器,如果我在代码中使用cores=2,我可以在一半的时间内得到结果(正如预期的那样),但当使用cores=3或cores=4时,我获得的性能与使用cores=2时相同。我有一个Intel core I3(2个核和4个线程),因此我想问题是只有2个核是真实的(我在其他计算机/处理器中测试代码,我得到相同的结果,只有真实的核似乎是有用的)。

我认为
多处理
更适合于您想要在python中展开工作的情况,这不是一个完全不同的过程。这一切都是关于使用
fork
并将内容从python进程传递到python进程,所以我认为它对您不起作用

在当前实现中,一旦生成了最大数量的子流程,代码将阻止新子流程的生成,直到当前所有批处理完成,因为
Popen.wait()
将阻止该特定子流程完成


我想你想要的是。我通过保持我的
subprocess.Popen
实例的映射(由pid映射),做了一些事情。只需增加最大数量的子进程,然后让
os.wait()
告诉您其中一个进程何时完成
os.wait()
将为您提供下一步完成的
Popen
实例的pid,您可以使用该pid为该子流程执行任何剩余清理。然后,让您的代码加速下一个子流程。

简单的方法:使用N核系统,进行一些基准测试运行,以确定您的应用程序需要以最高效率执行多少个流程。它可能是N、N+1或N+2个进程(例如,对于通常的软件构建
make
运行,文档通常建议将-j设置为N+1)。然后,对于生产运行,只需向用户或操作系统询问物理内核(不是线程)的数量,然后生成N或N+1或任何进程

更复杂、更酷、也不一定更好的方法:如果您可以测量完成的工作单元的吞吐量,您可以尝试在不知道/检测cpu/内核/线程数量的情况下动态调整进程的数量,如TCP窗口大小(如果您愿意)。从2个进程的目标开始,当第一个进程结束时,测量吞吐量并将目标+=1(即,将总数增加到3个进程)。测量、冲洗、重复。只要总吞吐量持续上升,就保持递增;当总吞吐量下降时,就递减。在混合中加入一些滞后,确保配置一个合理的上限


关于您的笔记本电脑示例,是的,这是一个多线程CPU,多线程将使某些工作负载比其他工作负载受益更多,而您的工作负载则没有从中受益:)

我不太理解模计算和等待逻辑。如果您只想运行数量可变的进程,但一次运行的核心进程不超过n个,那么最好的方法是使用Multiprocessing@andrew提供的进程池。如果cores=2,则每两步计算一次模,如果cores=3,则每三步计算一次模,等,即它将运行尽可能多的处理器可用的进程,然后等待,直到他们完成。。。可能这正是我要检查你的链接的池。如果池需要不同的时间长度,那么池会更有效(ps通常你会从超读中获得一些收益,因此你所描述的内容似乎有些奇怪)。过程几乎需要相同的时间。我尝试使用Pool,但并没有得到更好的结果(事实上,它们是最差的)。我必须检查我是否做错了什么。我认为你对多处理的看法是正确的。我试图用池做一些事情,但我的性能比我自己的代码差(当然,也许我做错了什么)。与我的实现相比,使用os.wait()的优势是什么?我相信(我使用的)子流程模块的想法是替换操作系统模块中的一些函数。阅读
os.wait
,看看我链接的示例代码,告诉我你不理解的地方。我只是不明白为什么我应该使用os.wait()而不是Popen.wait()。你的代码和我的代码看起来非常相似,我没有得到一个优于另一个的优势。。。如果我更改
if%cores==cores-1:
stament的
if len(proc\u list)==cores:
(当然我应该为proc\u list做一个新的赋值),我的代码可能会更容易阅读/理解现在我明白了什么让你困惑,我已经澄清了我的答案,见上文。验证你的假设。:-)尝试按照我的建议修复代码,然后重新进行计时测试。如果在进程数等于超线程数的情况下仍然看不到任何改进,那么需要包括更多细节,特别是如何测试计时以及子进程在做什么。子流程是否能够有效利用超线程,这一切都取决于