2016-07-13 31 views
7

私は、Python multiprocessingモジュールを使用して複数のワーカーを生成するユーティリティを持っています。私は好きなことをする優れたmemory_profilerユーティリティを使用してメモリ使用量を追跡できます。最終結果(私はこの質問の行ごとのメモリプロファイリングには関心がありません)。Pythonマルチプロセッシングとmemory_profilerを使用して複数のサブプロセスをプロファイリングする方法は?

この質問を設定するために、memory_profilerライブラリにあるexampleに似たメモリを割り当てるワーカー関数を持つ、より単純なバージョンのスクリプトを作成しました。次のように労働者は次のようになりますように4人の労働者のシーケンシャルなワークロードを考える

import time 

X6 = 10 ** 6 
X7 = 10 ** 7 

def worker(num, wait, amt=X6): 
    """ 
    A function that allocates memory over time. 
    """ 
    frame = [] 

    for idx in range(num): 
     frame.extend([1] * amt) 
     time.sleep(wait) 

    del frame 

は、次のとおりです。私のスクリプトをプロファイルする実行可能mprofを実行

if __name__ == '__main__': 
    worker(5, 5, X6) 
    worker(5, 2, X7) 
    worker(5, 5, X6) 
    worker(5, 2, X7) 

は、各ワーカーの実行次々に持つ70秒かかります。実行するスクリプトは、次のとおりです。これらの労働者はmultiprocessingと並行して行く持つスクリプトは最も遅い労働者と同じくらい遅いフィニッシュすることを意味します

Sequential Memory Generating Workers

$ mprof run python myscript.py 

には、以下のメモリ使用量のグラフを生成します(25秒)。

import multiprocessing as mp 

if __name__ == '__main__': 
    pool = mp.Pool(processes=4) 
    tasks = [ 
     pool.apply_async(worker, args) for args in 
     [(5, 5, X6), (5, 2, X7), (5, 5, X6), (5, 2, X7)] 
    ] 

    results = [p.get() for p in tasks] 

メモリプロファイラが実際に動作しない、または少なくともmprofを使用してエラーがないが、その結果は奇妙なビットです:次のようにそのスクリプトがある

enter image description here

簡単に見にアクティビティモニターには、実際には6つのPythonプロセスがあり、いずれもpython myscript.pyの場合はmprof、それから各ワーカーサブプロセスの場合は1つです。 mprofは、python myscript.pyプロセスのメモリ使用量のみを測定しているようです。

Python Processes in Activity Monitor

memory_profilerライブラリは、高度にカスタマイズ可能であり、私は、私は、各プロセスのメモリをキャプチャし、おそらくライブラリ自体を使用して、別のログファイルにそれらを書くことができなければならないことをかなり確信しています。私はどこから始めるべきか、そのレベルのカスタマイズにどのようにアプローチするのかは分かりません。

EDIT

mprofスクリプトを読んだ後、私はすべての子(フォーク)プロセスのメモリ使用量を合計-C旗を発見しました。これは、以下のように(改善くらい)のグラフにつながる:

Multiprocessing Workers with Include Children Flag

しかし、どのような私が探している私はすべての労働者(マスター)をプロットすることができるように時間をかけて、個々のサブプロセスのメモリ使用量であります同じグラフに表示されます。私の考えは、それぞれのサブプロセスmemory_usageを別のログファイルに書き込むことです。次に、それを視覚化することができます。

+0

誰もが興味を持っている場合は、この質問はhttps://github.com/fabianp/memory_profiler/issues/118でGitHubの上の開発者と議論されています。 – bbengfort

答えて

1

今日までに、まさにこれを行うメモリプロファイラライブラリに新機能が追加されました。この機能が必要な場合は、まずmemory_profilerを次のように更新します。

$ pip install -U memory_profiler 

メモリプロファイラのv0.44リリースをインストールする必要があります。これが事実であることを確認するには、実行アクションにhelpコマンドを使用します。

mprof run --help 
Usage: mprof run [options] 

Options: 
    --version    show program's version number and exit 
    -h, --help   show this help message and exit 
    --python    Activates extra features when the profiling executable 
         is a Python program (currently: function 
         timestamping.) 
    --nopython   Disables extra features when the profiled executable 
         is a Python program (currently: function 
         timestamping.) 
    -T INTERVAL, --interval=INTERVAL 
         Sampling period (in seconds), defaults to 0.1 
    -C, --include-children 
         Monitors forked processes as well (sum up all process 
         memory) 
    -M, --multiprocess Monitors forked processes creating individual plots 
         for each child 

あなたが-Mフラグが表示された場合、あなたが行ってもいいです!

次のようにあなたは、あなたのスクリプトを実行することができます

$ mprof run -M python myscript.py 
$ mprof plot 
をそして、あなたはこのようになります数字を取得する必要があります

mprof tracking individual child proccesses

あなたがよう--include-childrenフラグを使用する場合は、その注意をまあ、メインのプロセスメモリは、すべての子供とメインの合計メモリ使用量になります、これはまた有用なプロットです。

+0

これを実現するための@ fabian-pedregosaに感謝します! – bbengfort

+0

このモードでタイムスタンプと '@ profile'デコレータを有効にする方法はありますか?出来ますか? – petroslamb

+0

タイムスタンプを有効にすることについてどういう意味があるのですか? '@ profile'デコレータでこれが可能でなければならないと思います。同じ引数を使います。 – bbengfort

関連する問題