Python のモジュールを使用してコードを最適化しようとしていmultiprocessing.Pool
ますが、論理的に期待する速度向上の結果が得られません。
私が行っている主な方法は、多数のベクトルと固定された大きな疎行列の行列ベクトル積を計算することです。以下は、私が必要とするものを実行するおもちゃの例ですが、ランダムな行列を使用しています。
import time
import numpy as np
import scipy.sparse as sp
def calculate(vector, matrix = None):
for i in range(50):
v = matrix.dot(vector)
return v
if __name__ == '__main__':
N = 1e6
matrix = sp.rand(N, N, density = 1e-5, format = 'csr')
t = time.time()
res = []
for i in range(10):
res.append(calculate(np.random.rand(N), matrix = matrix))
print time.time() - t
メソッドは約30
数秒で終了します。
さて、 の各要素の計算はresults
他の計算の結果に依存しないため、並列計算を行うと処理が高速になると考えるのが自然です。アイデアは、4 つのプロセスを作成することであり、それぞれがいくつかの計算を行う場合、すべてのプロセスが完了するまでにかかる時間は約 1/2 減少するはず4
です。これを行うために、次のコードを書きました。
import time
import numpy as np
import scipy.sparse as sp
from multiprocessing import Pool
from functools import partial
def calculate(vector, matrix = None):
for i in range(50):
v = matrix.dot(vector)
return v
if __name__ == '__main__':
N = 1e6
matrix = sp.rand(N, N, density = 1e-5, format = 'csr')
t = time.time()
input = []
for i in range(10):
input.append(np.random.rand(N))
mp = partial(calculate, matrix = matrix)
p = Pool(4)
res = p.map(mp, input)
print time.time() - t
20
私の問題は、このコードの実行に数秒以上かかること2
です。さらに悪いことに、プールにプロセスが含まれていても、パフォーマンスは向上しません! 8
スピードアップが起こらない理由は何ですか?
注:私の実際の方法はもっと時間がかかり、入力ベクトルはファイルに保存されます。ファイルを分割してから、ファイル4
ごとに個別のプロセスでスクリプトを手動で実行すると、各プロセスはファイル全体の場合の 4 倍の速さで終了します (予想どおり)。このスピードアップ(明らかに可能です)がなぜ起こっていないのか混乱していますmultiprocessing.Pool
Edi : Multiprocessing.Pool により Numpy 行列の乗算が遅くなることがわかりました。この質問は関連している可能性があります。でもチェックしなきゃ。