51

単純なマルチプロセスPythonスクリプトをプロファイリングする方法を理解するのに苦労しています

import multiprocessing
import cProfile
import time
def worker(num):
    time.sleep(3)
    print 'Worker:', num

if __name__ == '__main__':
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        cProfile.run('p.start()', 'prof%d.prof' %i)

私は5つのプロセスを開始しているため、cProfileは5つの異なるファイルを生成します。それぞれの内部では、メソッド「worker」の実行に約3秒かかることを確認したいのですが、代わりに「start」メソッド内で何が起こっているかだけが表示されています。

誰かが私にこれを説明してくれれば幸いです。

更新:受け入れられた回答に基づく実例:

import multiprocessing
import cProfile
import time
def test(num):
    time.sleep(3)
    print 'Worker:', num

def worker(num):
    cProfile.runctx('test(num)', globals(), locals(), 'prof%d.prof' %num)


if __name__ == '__main__':
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        p.start()
4

3 に答える 3

27

p.start()プロセスの起動をプロファイリングしているので、あなたが言うように何が起こっているのかだけがp.start()わかり、サブプロセスが開始されると戻ってきます。workerサブプロセスで呼び出されるメソッド内のプロファイルを作成する必要があります。

于 2012-06-14T21:36:31.207 に答える
4

プロファイリングのためにソースコードを変更しなければならないのはクールではありません。あなたのコードがどのようになっているのか見てみましょう:

import multiprocessing
import time
def worker(num):
    time.sleep(3)
    print('Worker:', num)

if __name__ == '__main__':
    processes = []
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        p.start()
        processes.append(p)
    for p in processes:
        p.join()

ここに追加joinしたので、メインプロセスは、終了する前にワーカーを待機します。

cProfileの代わりに、を試してくださいviztracer

でインストールしpip install viztracerます。次に、マルチプロセス機能を使用します

viztracer --log_multiprocess your_script.py

タイムライン上のすべてのプロセスを示すhtmlファイルを生成します。(AWSDを使用してズーム/ナビゲートします)

スクリプトの結果

もちろん、これには興味のない情報(実際のマルチプロセッシングライブラリの構造など)も含まれます。あなたがすでにこれに満足しているなら、あなたは行ってもいいです。ただし、関数のみについてより明確なグラフが必要な場合worker()。機能を試してくださいlog_sparse

まず、ログに記録したい関数を飾ります@log_sparse

from viztracer import log_sparse

@log_sparse
def worker(num):
    time.sleep(3)
    print('Worker:', num)

次に実行しますviztracer --log_multiprocess --log_sparse your_script.py

スパースログ

タイムラインには、3秒かかるワーカー関数のみが表示されます。

于 2020-11-12T20:36:02.587 に答える
1

複雑なプロセス構造があり、コードの特定の部分、またはプロセスの特定の作業コアをプロファイリングする場合は、プロファイラーをポイントして、そこで統計を収集できます(メソッドhttps://docsの有効化と無効化を参照してください)。 python.org/3.6/library/profile.html#module-cProfile)。これがあなたにできることです:

import cProfile

def my_particular_worker_code()
    pr = cProfile.Profile()
    pr.enable()

    # Process stuff to be profiled

    pr.disable()
    pr.print_stats(sort='tottime')  # sort as you wish

レポートをファイルにドロップすることもできます。

于 2021-03-26T14:01:53.300 に答える