昨日

2016-07-15 23 views
2

マルチプロセッシングと並行して辞書を埋める私は質問を:Reading data in parallel with multiprocess昨日

、私は非常に良い答えを得た、と私は正しいとしてマークされた答えに記載されたソリューションを実装しました。

def read_energies(motif): 
    os.chdir("blabla/working_directory") 
    complx_ener = pd.DataFrame() 
    # complex function to fill that dataframe 
    lig_ener = pd.DataFrame() 
    # complex function to fill that dataframe 
    return motif, complx_ener, lig_ener 

COMPLEX_ENERGIS = {} 
LIGAND_ENERGIES = {} 
p = multiprocessing.Pool(processes=CPU) 
for x in p.imap_unordered(read_energies, peptide_kd.keys()): 
    COMPLEX_ENERGIS[x[0]] = x[1] 
    LIGAND_ENERGIES[x[0]] = x[2] 

私はちょうどpeptide_kd.keys()を反復処理し、一つDataFrames 1を埋めるかのようしかし、この解決策は、同じ時間がかかります。どうしてこんなことに?希望のdictsを並行していっぱいにして実際にスピードを上げる方法はありますか?私は48コアHPC上で実行しています。

+0

マルチプロセッシングを使用するオーバーヘッドが、複雑な関数処理を行うオーバーヘッドよりも大きい場合があります。おそらく、 'read_energies()'が可変個のデータフレームを処理すると、その都度ポイントを調整することができるようになり、それが有利になったでしょう。 – martineau

答えて

3

(1)各プロセスを起動し、(2)いくつかのプロセスにまたがってpandas.DataFrame(など)をコピーする必要があります。 dictを並列に埋め込む必要がある場合は、共有メモリdictを使用することをお勧めします。上書きされないキーがないと、簡単ですし、ロックについて心配する必要もありません。

(ここではmultiprocessingのフォークですが、私は通訳者から説明することができます。そうでなければ、__main__から以下を行う必要があります)。オーバーヘッドの一部が減少するように

>>> from multiprocess import Process, Manager 
>>> 
>>> def f(d, x): 
... d[x] = x**2 
... 
>>> manager = Manager() 
>>> d = manager.dict() 
>>> job = [Process(target=f, args=(d, i)) for i in range(5)] 
>>> _ = [p.start() for p in job] 
>>> _ = [p.join() for p in job] 
>>> print d 
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16} 

このソリューションは、プロセス間で共有することdictのコピーを作成しません。 pandas.DataFrameのような大きなオブジェクトの場合は、x**2のような単純な操作のコストに比べて重要です。同様に、Processを生成するには時間がかかる可能性があります。スレッドを使用すると(軽量オブジェクトの場合は)上記の処理をさらに高速化することができます(最初に投稿したソリューションまたは上記の鉱山のいずれかにmultiprocessではなくmultiprocess.dummy)。

あなたがDataFramesを共有する必要性を(質問が尋ねると、あなたのコードが示しているの代わりとして)行う場合は、共有メモリnumpy.ndarrayを作成することによって、それを行うことができるかもしれません。

+0

答えをありがとう!私は今これを試してみるつもりですが、まず何かを聞きたいです。私は言及した '共有された'データフレーム(私が推測する変数)の違いを理解していません。私のコードが私が共有DataFrameを使用することを意味するのはなぜですか?私が並行してやりたい仕事は、あなたが記述したとおりで、辞書をいっぱいにして、後で別のやり方でそれを使う(その中のデータを読む)が、その中の何も変わらない。 –

+0

私が共有メモリ配列を調べる理由は、各 'Process'から2つの' DataFrame'インスタンスを返すことです。しかし、あなたがメタコードを提示しただけで、あなたがそれをする必要があるかしないかを指摘するのは難しいです。 –

+0

オハイオ州参照してください。私は 'DataFrames'の両方が必要です。そのうち2つを返すのは問題なのでしょうか?これを2つの別々のステップで行うほうが簡単でしょうか? –