2016-03-26 11 views
1

コンテキスト:私は自分のエンジン(この時点では4つのエンジン)に散在している配列を持っていて、配列の各ポイントに任意の反復回数の関数を適用したい結果の配列をエンジンから集めて分析を実行します。例えばスキャッタ/ギャザーを使用したIpyparallel低速実行

Iが散在しているデータ点のアレイと、各データポイントに反復数を有する:

data_points = range(16) 
iterations = 10 
dview.scatter('points', data_points) 

Iがエンジンにプッシュされ、例えば、ユーザ提供の関数を有します。

def user_supplied_function(point): 
    return randint(0, point) 

dview.push(dict(function_one = user_supplied_function)) 

私の結果と並列実行のためのリスト:

result_list = [] 
for i in range(iterations): 
    %px engine_result = [function_one(j) for j in points] 
    result_list.append(dview.gather('engine_result')) 

Issue:これはうまくいき、エンジンから必要な結果を得ることができますが、反復回数が増えるにつれてループの実行には時間がかかります。 50ポイントの1000回の反復が完了するまでに15秒以上かかるポイントまで。このタスクのシーケンシャルバージョンは1秒未満しかかかりません。

これを引き起こす原因は何ですか? gather()から渡されるメッセージのオーバーヘッドになるのでしょうか?もしそうなら誰もどんな解決策を提案することができますか?

答えて

0

それを実演しました。結局、gather().append()からのオーバーヘッドでした。最も簡単な修正はエンジンが作業を終えた後で、各反復を行うのではなく、gather()です。

%autopx 
engine_result = [] 
for i in xrange(iterations): 
    engine_result += [[function_one(j) for j in points]] 
%autopx 
result_list = list(dview.gather('engine_result')) 

この

ソリューションは、しかしながら、各エンジンからの結果は、隣同士の代わりに反復回数順に並べて配置されているリストの乏しいフォーマットリストに結果を得ます。次のコマンドはリストを配布し、繰り返しごとにサブリストを展開します。

gathered_list = [None] * iterations 
gathered_list = [[result_list[j * iterations + i] for j in xrange(len(result_list)/iterations)] for i in xrange(iterations)] 
gathered_list = [reduce(lambda x, y: x.extend(y) or x, z) for z in gathered_list] 
関連する問題