2016-09-13 1 views
1

ちょっと私は基本的にPlayerオブジェクトを持つWorld ObjectであるPythonでいくつかのコードを持っています。ある時点で、プレイヤーはすべて世界の状態を取得し、行動を返す必要があります。プレイヤーが行う計算は独立しており、それぞれのプレイヤーインスタンスのインスタンス変数のみを使用します。最も簡単な方法で呼び出しを並列化できますか?

while True: 
    #do stuff, calculate state with the actions array of last iteration 
    for i, player in enumerate(players): 
     actions[i] = player.get_action(state) 

forループを並列実行する最も簡単な方法は何ですか?それとも、これは私が想定しているよりも大きな仕事ですか?

+2

「マルチプロセッシング」以外のものはありますか? –

+0

@ IgnacioVazquez-Abrams私はプールオブジェクトとIRC(freenode #python)上のマルチプロセッシングモジュールのマップ機能を使用することについて尋ねました。 – fubal

+0

とにかくあなたのコードが既に動作していて、この点がプロファイリングによるボトルネックであることがわかったら、このパラレル化について心配する必要があります。さもなければ、あなたはまったく必要のないかもしれないものについて早すぎる最適化に苦しんでいるだけです。 – jsbueno

答えて

2

最も簡単な方法は、(ちょうどmapと同じように動作する)multiprocessing.Pool.mapを使用することです:

import multiprocessing 
pool = multiprocessing.Pool() 

def do_stuff(player): 
    ... # whatever you do here is executed in another process 

while True: 
    pool.map(do_stuff, players) 

注しかし、これは複数のプロセスを使用していること。 GILのためにPythonでマルチスレッドを行う方法はありません。

通常、並列化はスレッド内で実行されます。これらのスレッドは、同じプロセスで実行されるため、プログラム内の同じデータにアクセスできます。プロセス間でデータを共有するには、パイプ、ソケット、ファイルなどのIPC(プロセス間通信)メカニズムを使用する必要があります。また、産卵プロセスは産卵スレッドよりもはるかに遅いです。

他のソリューションが含まれます:

  • ベクトル:ベクトルや行列の計算として、あなたのアルゴリズムを書き換え、GIL
  • を持っていない別のPythonディストリビューションを使用して
  • を実行するためにハードウェアアクセラレーションライブラリを使用しますあなたの並列コードを別の言語で実装してPythonから呼び出す

データを共有する必要があるときに大きな問題が発生しますプロセス間/スレッド間たとえば、コードでは、各タスクはactionsにアクセスします。 の状態を共有する場合は、concurrent programmingへようこそ。これははるかに大きな仕事であり、ソフトウェアで最も難しいことの1つです。

+0

ありがとう!複数のプロセスを使用することについては何が悪いですか? – fubal

+0

複数のプロセスでは、グローバルデータを他のプロセスにも持たせる必要があります。そのデータを明示的に同期化しない限り、それは発散します。 グローバルデータがなく、これらの関数でチェックされる(大きなデータ構造は渡されない)場合、複数のプロセスが機能します。 – jsbueno

+0

その場合、 "lelo"を使うこともできます:https://pypi.python.org/pypi/lelo/1.0rc3dev – jsbueno

関連する問題