2

私は、FORTRAN を使用した数値計算と OpenMP を使用した並列化に強いバックグラウンドを持っており、多くの問題で簡単に使用できることがわかりました。PYTHON に切り替えたのは、(少なくとも私にとっては) 開発がはるかに楽しいからですが、数値タスクの並列化は OpenMP よりもはるかに退屈に思えます。私はしばしば、大規模な (数十 GB) データ セットをメイン メモリにロードし、メイン メモリ (共有データ) にデータのコピーを 1 つだけ保持しながら並列に操作することに関心があります。私はこれに PYTHON モジュール MULTIPROCESSING を使い始め、この一般的な例を思いつきました:

#test cases    
#python parallel_python_example.py 1000 1000
#python parallel_python_example.py 10000 50

import sys
import numpy as np
import time
import multiprocessing
import operator

n_dim = int(sys.argv[1])
n_vec = int(sys.argv[2])

#class which contains large dataset and computationally heavy routine
class compute:
    def __init__(self,n_dim,n_vec):
        self.large_matrix=np.random.rand(n_dim,n_dim)#define large random matrix
        self.many_vectors=np.random.rand(n_vec,n_dim)#define many random vectors which are organized in a matrix
    def dot(self,a,b):#dont use numpy to run on single core only!!
        return sum(p*q for p,q in zip(a,b))
    def __call__(self,ii):# use __call__ as computation such that it can be handled by multiprocessing (pickle)
        vector = self.dot(self.large_matrix,self.many_vectors[ii,:])#compute product of one of the vectors and the matrix
        return self.dot(vector,vector)# return "length" of the result vector

#initialize data
comp = compute(n_dim,n_vec)

#single core
tt=time.time()
result = [comp(ii) for ii in range(n_vec)]
time_single = time.time()-tt
print "Time:",time_single

#multi core
for prc in [1,2,4,10]:#the 20 case is there to check that the large_matrix is only once in the main memory
  tt=time.time()
  pool = multiprocessing.Pool(processes=prc)
  result = pool.map(comp,range(n_vec))
  pool.terminate()
  time_multi = time.time()-tt  
print "Time using %2i processes. Time: %10.5f, Speedup:%10.5f" % (prc,time_multi,time_single/time_multi)

私のマシン (Fedora 18 を使用する 64 ビット Linux) で 2 つのテスト ケースを実行し、次の結果を得ました。

andre@lot:python>python parallel_python_example.py 10000 50
Time: 10.3667809963
Time using  1 processes. Time:   15.75869, Speedup:   0.65785
Time using  2 processes. Time:   11.62338, Speedup:   0.89189
Time using  4 processes. Time:   15.13109, Speedup:   0.68513
Time using 10 processes. Time:   31.31193, Speedup:   0.33108
andre@lot:python>python parallel_python_example.py 1000 1000
Time: 4.9363951683
Time using  1 processes. Time:    5.14456, Speedup:   0.95954
Time using  2 processes. Time:    2.81755, Speedup:   1.75201
Time using  4 processes. Time:    1.64475, Speedup:   3.00131
Time using 10 processes. Time:    1.60147, Speedup:   3.08242

私の質問は、ここで MULTIPROCESSING モジュールを誤用しているのでしょうか? それとも、これは PYTHON での方法ですか (つまり、python 内で並列化せず、numpy の最適化に完全に依存しています)?

4

3 に答える 3

0

提供されたテスト結果から、2 コア マシンでテストを実行したようです。私はそれらの1つを持っていて、テストコードを実行して同様の結果を得ました。これらの結果が示しているのは、並列計算に適した数値アプリケーションでは、コアよりも多くのプロセスを実行してもほとんどメリットがないということです。

私の 2 コア マシンでは、CPU の約 20% が単に環境を維持するために吸収されているため、2 つのプロセスを実行して 1.8 の改善が見られた場合、利用可能なすべてのサイクルが自分の作業に使用されていると確信できます。基本的に、並列数値計算では、コア数が多いほど、作業に使用できるコンピューターの割合が高くなります。

他のポスターは、Numpy、Scipy、Cython などを指摘する点で完全に正しいです。基本的には、最初に計算で使用するサイクルをできるだけ少なくし、次に何らかの形でマルチプロセッシングを使用して、問題に適用するより多くのサイクルを見つける必要があります。

于 2013-07-24T11:51:39.743 に答える