4

我有一个庞大的数据集,我必须为它的每个点计算一系列属性。我的代码真的很慢,我想让它以某种方式更快地并行化 do 循环。我希望每个处理器为我的数据的有限子样本计算“一系列属性”,然后将所有属性连接到一个数组中。我将尝试用一个例子来解释我必须做什么。

假设我的数据集是数组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功能不感兴趣。我正在一个循环中执行一系列操作。我完全知道循环是不好的,矢量运算总是比它们更可取,但在这种情况下,我真的必须做一个循环。我不会详细介绍我的问题,因为这会给这个问题增加不必要的复杂性。我想拆分我的循环,以便每个处理器执行它的一部分,这意味着我可以运行我的代码 40 次,每次循环的 1/40 和合并结果,但这将是愚蠢的。这是一个简短的例子

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

我想要的是使用 40 cpu 来做到这一点:

    for npcu in arange(0,40):
       for i in arange(len(x)/40*ncpu,len(x)/40*(ncpu+1)):
          # do some complicated stuff

用python可能吗?

4

3 回答 3

3

并行化并非易事,但您可能会发现numexpr很有用。

对于数值工作,你真的应该研究 numpy 给你的实用程序(矢量化和类似的),这些通常会给你一个很好的加速作为工作的基础。

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


在旁注中,python 的多线程比其他语言更重要,因为 CPython 具有全局解释器锁 (GIL),它不允许两个 python 代码部分同时在同一个解释器中运行(即有没有真正的多线程纯python代码)。然而,对于 I/O 和繁重的计算,第三方库往往会释放该锁,因此有限的多线程是可能的。

这增加了必须互斥共享数据访问和类似的通常多线程的麻烦。

于 2012-06-26T15:28:29.427 回答
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

应 Sven 的要求,这里的结果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
于 2012-06-26T15:51:43.587 回答
0

我建议你看看 cython: http ://www.cython.org/

它使您能够非常快速地为 python 创建 c 扩展,并与 numpy 很好地集成。这是一个很好的教程,可以帮助您入门:http ://docs.cython.org/src/tutorial/numpy.html

于 2012-06-26T16:44:14.473 回答