2012-06-26 111 views
4

我有一个庞大的数据集,我必须计算它的每一个点的一系列属性。我的代码非常慢,我想让它更快地并行化do循环。我希望每个处理器为我的数据的有限子样本计算“一系列属性”,然后将所有属性连接在一个数组中。 我会尝试解释我必须要做的一个例子。需要帮助来并行python循环

比方说,我的数据集是数组x

x = linspace(0,20,10000) 

的“财产”我希望得到的是,例如,平方根x

prop=[] 
for i in arange(0,len(x)): 
    prop.append(sqrt(x[i])) 

问题我如何平行上面的循环?假设我有4个处理器,并且我希望每个处理器计算10000/4 = 2500点的sqrt。

我试着看过一些Python模块,如multiprocessingmpi4py,但从指南我找不到这样一个简单的问题的答案。

编辑

我要谢谢大家的宝贵意见和链接,您为我提供。不过,我想澄清一下我的问题。无论如何,我对sqrt功能不感兴趣。 我正在循环中执行一系列操作。我完全知道循环是坏的,矢量操作总是比他们更可取,但在这种情况下,我真的必须做一个循环。我不会详细讨论我的问题,因为这会给这个问题增加不必要的复杂性。 我想分割我的循环,以便每个处理器都能完成它的一部分,这意味着我可以用每个循环的1/40来运行我的代码40次,并且合并结果,但这将是愚蠢的。 这是一个简单的例子

 for i in arange(0,len(x)): 
     # do some complicated stuff 

我要的是用40级的CPU来做到这一点:

​​

那是可能的,或者不使用Python?

+6

对于这个特殊的例子,你会比使用'numpy.sqrt(x)'而不是Python循环的单纯因子4快得多。你的真实任务可能也是如此。 –

+1

感谢您的回答,但是我的真正任务比执行sqrt更复杂。我只是想知道为什么我找不到任何简单的python循环并行化的例子。 – Brian

+6

根据我的经验,矢量化是在99%的情况下加速数值Python循环的方法,即使它们更复杂。描述你的真实功能,我可以告诉你如何进行矢量化。 –

回答

2

我不确定这是你应该如何做的事情,因为我期望numpy有一个更有效的方法去实现它,但是你的意思是这样吗?

import numpy 
import multiprocessing 

x = numpy.linspace(0,20,10000) 
p = multiprocessing.Pool(processes=4) 

print p.map(numpy.sqrt, x) 

以下是两种解决方案的结果timeit。正如@SvenMarcach指出的那样,然而,如果使用更昂贵的功能,多处理将开始变得更加有效。

% python -m timeit -s 'import numpy; x=numpy.linspace(0,20,10000)' 'prop=[]                   
for i in numpy.arange(0,len(x)): 
     prop.append(numpy.sqrt(x[i]))' 
10 loops, best of 3: 31.3 msec per loop 

% python -m timeit -s 'import numpy, multiprocessing; x=numpy.linspace(0,20,10000) 
p = multiprocessing.Pool(processes=4)' 'l = p.map(numpy.sqrt, x)' 
10 loops, best of 3: 102 msec per loop 

在斯文的要求,这里是l = numpy.sqrt(x)其结果是比任何替代品更快显著

% python -m timeit -s 'import numpy; x=numpy.linspace(0,20,10000)' 'l = numpy.sqrt(x)' 
10000 loops, best of 3: 70.3 usec per loop 
+1

'multiprocessing'方法比较慢,因为每次迭代执行的函数都是相当简单的。如果你在每次迭代中都有一个“胖”函数,你实际上会看到一个加速。在时机中加入'l = numpy.sqrt(x)'也会很有趣。 –

+0

@SvenMarnach这是一个很好的观点,我唯一使用'multiprocessing'的时间很多,就像获取很多网页一样,它显然要快得多。我没有考虑过sqrt实际上是一个相当微不足道的函数,我试图编辑我的帖子来反映这一点,以及添加'numpy.sqrt(x)'的结果。 –

+1

请注意,最后的解决方案实际上比普通Python循环快450倍。它不是在另外两个之间!这又是我上面评论的重点。 –

3

并行并不重要,但是您可能会发现numexpr有用。

对于数值工作,你真的应该看看numpy的给你(vectorize和类似)的实用工具,这些给你通常是一个好加速的基础上工作。

对于更复杂的非数值情况,您可以使用multiprocessing(请参阅注释)。


在一个旁注,多线程是更加非平凡与Python比用其他语言,是CPython的具有Global Interpreter Lock (GIL)其中不允许的Python代码两段同时在相同的解释器运行(即没有真正的多线程纯Python代码)。对于I/O和繁重的计算,不过第三方库倾向于释放该锁,因此有限的多线程是可能的。

这增加了必须互斥共享数据访问和类似的常见多线程滋扰。

+0

感谢您的链接。但我希望找到一个python中最简单的并行循环例子的链接。 – Brian

+1

@Matteo:这里你去:http://docs.python.org//library/multiprocessing.html#using-a-pool-of-workers –

+1

谢谢,但从这个例子,它不是很清楚(至少不是对我来说很清楚)我如何在每个处理器之间分配任务。 – Brian