2015-11-18 83 views
14

我想在一个简单的例子上运行一个并行循环。
我在做什么错?写一个并行循环

from joblib import Parallel, delayed 
import multiprocessing 

def processInput(i): 
     return i * i 

if __name__ == '__main__': 

    # what are your inputs, and what operation do you want to 
    # perform on each input. For example... 
    inputs = range(1000000)  

    num_cores = multiprocessing.cpu_count() 

    results = Parallel(n_jobs=4)(delayed(processInput)(i) for i in inputs) 

    print(results) 

与代码的问题是,当在Python 3在Windows环境中执行时,它蟒蛇执行并行作业的num_cores实例,但只有一个是积极的。这不应该是这种情况,因为处理器的活动应该是100%而不是14%(在i7-8逻辑核心下)。

为什么额外的实例没有做任何事情?

+0

您是否收到任何错误消息?它对我来说运行良好......。缩进应该是4个空格而不是一个... –

+0

我有同样的问题。问题是代码只能运行在一个核心而不是n核心上。 –

回答

17

继续您的要求提供工作多处理代码,我建议你使用pool_map(如果延迟的功能不重要),我会给你一个例子,如果你的python3的工作值得一提,你可以使用starmap。 另外值得一提的是,如果返回结果的顺序不必与输入顺序相对应,则可以使用map_sync/starmap_async。

import multiprocessing as mp 

def processInput(i): 
     return i * i 

if __name__ == '__main__': 

    # what are your inputs, and what operation do you want to 
    # perform on each input. For example... 
    inputs = range(1000000) 
    # removing processes argument makes the code run on all available cores 
    pool = mp.Pool(processes=4) 
    results = pool.map(processInput, inputs) 
    print(results) 
+0

我喜欢这个简单,所以我试了一下。我得到一个TypeError:无法序列化'_io.TextIOWrapper'对象。我的功能非常复杂,我没有时间深入了解它,只是关于您是否具有复杂功能的评论,这可能无法正常工作 – Nick

+0

序列化是每个多进程程序的主要部分。为了尝试和缓解这些问题,我建议检查你的复杂功能,并检查它的哪一部分确实需要多处理解决方案,并尝试将它从复杂函数中解耦,这将简化序列化,甚至可能使其不必要。 – Fanchi

2

在Windows上,多处理模块使用'spawn'方法来启动多个python解释器进程。这比较慢。并行尝试在运行代码时很聪明。特别是,它试图调整批量大小,因此批量执行需要大约半秒。 (参见https://pythonhosted.org/joblib/parallel.html的参数的batch_size)

processInput()函数运行如此之快,并行确定它是更快地在一个处理器上串联运行的作业比加速旋转多个Python解释和并行运行的代码。

如果您想强制您的示例在多个内核上运行,请尝试将batch_size设置为1000或使processInput()更复杂,以便执行时间更长。

编辑:工作例如在Windows上,显示在使用多个进程(我使用Windows 7):

from joblib import Parallel, delayed 
from os import getpid 

def modfib(n): 
    # print the process id to see that multiple processes are used, and 
    # re-used during the job. 
    if n%400 == 0: 
     print(getpid(), n) 

    # fibonacci sequence mod 1000000 
    a,b = 0,1 
    for i in range(n): 
     a,b = b,(a+b)%1000000 
    return b 

if __name__ == "__main__": 
    Parallel(n_jobs=-1, verbose=5)(delayed(modfib)(j) for j in range(1000, 4000)) 
+0

你能否提出一个代码修改,以便任务能够并行有效地执行?由于上面的代码是作为joblib使用的示例给出的,因此应该有一个实际可行的示例。 –