私は先物モジュールを初めて使用し、並列化の恩恵を受ける可能性のあるタスクを持っています。しかし、スレッドの関数とプロセスの関数をセットアップする方法を正確に理解できないようです。誰でもこの問題について何か助けていただければ幸いです。
粒子群最適化 (PSO)を実行しています。PSO 自体について詳しくは説明しませんが、コードの基本的なレイアウトは次のとおりです。
Particle
メソッドを備えたクラスがありますgetFitness(self)
(これは、いくつかのメトリックを計算し、それを に保存しますself.fitness
)。PSO シミュレーションには、複数の粒子インスタンスがあります (10 を簡単に超えます。一部のシミュレーションでは 100 または 1000 ですらあります)。
ときどき、粒子の適合度を計算する必要があります。現在、私は for ループでこれを行います:
for p in listOfParticles:
p.getFitness(args)
ただし、各粒子の適合度は互いに独立して計算できることに気付きました。これにより、このフィットネス計算は並列化の最有力候補になります。確かに、私はすることができmap(lambda p: p.getFitness(args), listOfParticles)
ました。
今、私はこれを簡単に行うことができますfutures.ProcessPoolExecutor
:
with futures.ProcessPoolExecutor() as e:
e.map(lambda p: p.getFitness(args), listOfParticles)
呼び出しの副作用はp.getFitness
各パーティクル自体に格納されているため、 から返されることを心配する必要はありませんfutures.ProcessPoolExecutor()
。
ここまでは順調ですね。しかし今、私はそれが新しいプロセスを作成することに気付きましたProcessPoolExecutor
。つまり、メモリをコピーするため、速度が低下します。メモリを共有できるようにしたいので、スレッドを使用する必要があります。それは良いことですが、各プロセス内で複数のスレッドを使用して複数のプロセスを実行する方が高速になる可能性が高いことに気付くまでは.
ここで問題が発生します。
これまでに見た例に基づいて、 は でThreadPoolExecutor
動作しlist
ます。そうProcessPoolExecutor
です。そのため、単一のオブジェクトを処理する必要があるため、反復的にProcessPoolExecutor
ファームアウトするThreadPoolExecutor
ことはできません(以下に投稿された私の試みを参照してください)。
一方で、必要なスレッドの数を把握するために独自の魔法を実行したいので、自分自身をスライスすることはできません。ThreadPoolExecutor
listOfParticles
ThreadPoolExecutor
したがって、大きな問題 (ついに) :
プロセスとスレッドの両方を使用して以下を効果的に並列化できるように、コードをどのように構成すればよいでしょうか。
for p in listOfParticles:
p.getFitness()
これは私が試してきたことですが、うまくいかないことがわかっているので、あえて実行しようとしません。
>>> def threadize(func, L, mw):
... with futures.ThreadpoolExecutor(max_workers=mw) as executor:
... for i in L:
... executor.submit(func, i)
...
>>> def processize(func, L, mw):
... with futures.ProcessPoolExecutor() as executor:
... executor.map(lambda i: threadize(func, i, mw), L)
...
これを修正する方法、またはアプローチを改善する方法についての考えをいただければ幸いです
念のため、私は python3.3.2 を使用しています