0

次のような Python スクリプトがあります。

from modules import functions
a=1
parameters = par_vals
for i in range(large_number):
    #do lots of stuff dependent on a, plot stuff, save plots as png

これを "a" の値で実行すると、30 分かかり、6 コア マシンの 1 コアしか使用しません。

「a」の100個の異なる値に対してこのコードを実行したい

問題は、これをどのように並列化して、すべてのコアを使用し、「a」のすべての値を試すことができるかということです。

オンラインの提案に続く私の最初のアプローチは次のとおりです。

from joblib import Parallel, delayed
def repeat(a):
    from modules import functions
    parameters = par_vals
    for i in range(large_number):
        #do lots of stuff dependent on a, plot stuff, save plots as png

A=list_100_a #list of 100 different a values
Parallel(n_jobs=6,verbose=0)(delayed(repeat)(a) for a in A)

これにより、コンピューター内のすべてのコアが正常に使用されましたが、同時に a の 100 個の値すべてを計算していました。4 時間後には、64GB の RAM メモリと 64GB のスワップ メモリが飽和状態になり、パフォーマンスが大幅に低下しました。そのため、forループ内で一度に6回実行する関数を手動でキューに入れようとしました。しかし問題は、メモリも消費されることでした。

どこに問題があるのか​​わからない。どういうわけか、プログラムが不要なメモリを保持していると思います。

このメモリの問題が発生しないようにするにはどうすればよいですか。

要約すると、「a」の特定の値に対してこの関数を実行すると、すべて問題ありません。「a」の6つの値に対してこの関数を並行して実行すると、すべて問題ありません。この関数を並行して順次実行すると、コンピューターが機能しなくなるまでメモリが徐々に増加します。


更新: 理由はわかりませんが、メモリの問題の解決策を見つけました。

matplotlib のバックエンドを「Agg」に変更しても、メモリの問題が発生しなくなったようです。

インポートの前にこれを追加するだけで問題ありません。

from matplotlib import use
use('Agg')
4

1 に答える 1

1

これが私がそれを行う方法ですmultiprocessing。あなたのrepeat関数を使用して、 の 1 つの値に対して作業を行いますa

def repeat(a):
    from modules import functions
    parameters = par_vals
    for i in range(large_number):
        #do lots of stuff dependent on a, plot stuff, save plots as png

次に、次multiprocessing.poolのように使用します。

import multiprocessing

pool = multiprocessing.Pool(processes=6)  # Create a pool with 6 workers.
A=list_100_a #list of 100 different a values

# Use the workers in the pool to call repeat on each value of a in A.  We
# throw away the result of calling map, since it looks like the point of calling
# repeat(a) is for the side effects (files created, etc).
pool.map(repeat, A) 

# Close the pool so no more jobs can be submitted to it, then wait for 
# all workers to exit.
pool.close()
pool.join()

repeat を呼び出した結果が必要な場合は、単にresult = pool.map(repeat, A).

問題が発生することはないと思いますが、を使用するためのプログラミング ガイドラインmultiprocessingを読むことも役に立ちます。

于 2013-09-28T15:04:12.573 に答える