4

私は巨大なデータセットを持っており、そのすべてのポイントについて一連のプロパティを計算する必要があります。私のコードは非常に遅いので、何らかの方法で do ループを並列化して高速化したいと考えています。各プロセッサで、データの限定されたサブサンプルの「一連のプロパティ」を計算し、すべてのプロパティを 1 つの配列に結合したいと考えています。例を使って何をしなければならないかを説明しようとします。

私のデータセットが配列であるとしましょうx

x = linspace(0,20,10000)

取得したい「プロパティ」は、たとえば次の平方根ですx

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

問題は、上記のループをどのように並列化できるかです。4 つのプロセッサがあり、それぞれに 10000/4=2500 ポイントの平方根を計算させたいとします。

multiprocessingやのようないくつかのpythonモジュールを見てみましmpi4pyたが、ガイドからはそのような単純な質問に対する答えが見つかりませんでした。

編集

貴重なコメントとリンクを提供してくださった皆様に感謝します。しかし、私は私の質問を明確にしたいと思います。私はsqrt機能にまったく興味がありません。ループ内で一連の操作を行っています。私はループが悪いことを完全に知っており、ベクトル演算は常にループよりも望ましいですが、この場合は実際にループを実行する必要があります。この質問に不必要な複雑さが追加されるため、問題の詳細には立ち入りません。各プロセッサがその一部を実行するようにループを分割したいと思います。つまり、それぞれのループの 1/40 でコードを 40 回実行し、結果をマージできますが、これはばかげています。これは簡単な例です

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

私が望むのは、これを行うために40 cpusを使用することです:

    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 には、Python コードの 2 つのセクションを同じインタープリターで同時に実行することを禁止するグローバル インタープリター ロック (GIL)があるためです (つまり、実際のマルチスレッド化された純粋な 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 に答える