31

そこで、スレッド化と比較して、マルチプロセッシング モジュールが CPU バウンドの作業でどのようにスケーリングするかを確認するために、いくつかのテスト コードを作成しました。Linux では、期待どおりのパフォーマンスの向上が得られます。

Linux (デュアル クアッド コア xeon):
serialrun には 1192.319 ミリ秒かかりました
並列実行には 346.727 ミリ秒かかりました
threadedrun には 2108.172 ミリ秒かかりました

私のデュアル コア MacBook Pro は同じ動作を示します。

osx (デュアルコア macbook pro)
serialrun には 2026.995 ミリ秒かかりました
並列実行には 1288.723 ミリ秒かかりました
threadedrun には 5314.822 ミリ秒かかりました

次に、Windows マシンで試してみたところ、非常に異なる結果が得られました。

窓 (i7 920):
serialrun には 1043.000 ミリ秒かかりました
parallelrun には 3237.000 ミリ秒かかりました
threadedrun には 2343.000 ミリ秒かかりました

マルチプロセッシング アプローチが Windows で非常に遅いのはなぜですか?

テストコードは次のとおりです。

#!/usr/bin/env パイソン

マルチプロセッシングのインポート
スレッドのインポート
輸入時間

def print_timing(func):
    デフラッパー(*引数):
        t1 = 時間.時間()
        res = func(*引数)
        t2 = 時間.時間()
        print '%s は %0.3f ms かかりました' % (func.func_name, (t2-t1)*1000.0)
        解像度を返す
    リターンラッパー


デフカウンター():
    xrange(1000000) の i の場合:
        合格

@print_timing
def serialrun(x):
    xrange(x) の i の場合:
        カウンター()

@print_timing
デフパラレルラン(x):
    proclist = []
    xrange(x) の i の場合:
        p = multiprocessing.Process(ターゲット=カウンター)
        proclist.append(p)
        p.start()

    proclistの私のために:
        参加する()

@print_timing
def threadedrun(x):
    スレッドリスト = []
    xrange(x) の i の場合:
        t = threading.Thread(ターゲット=カウンター)
        threadlist.append(t)
        t.start()

    スレッドリストの私のために:
        参加する()

デフメイン():
    シリアルラン(50)
    並列実行(50)
    スレッドラン(50)

__name__ == '__main__' の場合:
    主要()
4

5 に答える 5

26

マルチプロセッシングに関するPythonのドキュメントは、Windowsの問題に対するos.fork()の欠如を非難しています。ここで適用できる場合があります。

psycoをインポートするとどうなるかを確認してください。まず、easy_installします。

C:\Users\hughdbrown>\Python26\scripts\easy_install.exe psyco
Searching for psyco
Best match: psyco 1.6
Adding psyco 1.6 to easy-install.pth file

Using c:\python26\lib\site-packages
Processing dependencies for psyco
Finished processing dependencies for psyco

これをPythonスクリプトの先頭に追加します。

import psyco
psyco.full()

これらの結果は次のように表示されません。

serialrun took 1191.000 ms
parallelrun took 3738.000 ms
threadedrun took 2728.000 ms

私はこれらの結果を次のように取得します:

serialrun took 43.000 ms
parallelrun took 3650.000 ms
threadedrun took 265.000 ms

Parallelはまだ遅いですが、他のものはゴムを燃やします。

編集:また、マルチプロセッシングプールで試してみてください。(これは初めての試みで、とても速いので、何かが足りないに違いないと思います。)

@print_timing
def parallelpoolrun(reps):
    pool = multiprocessing.Pool(processes=4)
    result = pool.apply_async(counter, (reps,))

結果:

C:\Users\hughdbrown\Documents\python\StackOverflow>python  1289813.py
serialrun took 57.000 ms
parallelrun took 3716.000 ms
parallelpoolrun took 128.000 ms
threadedrun took 58.000 ms
于 2009-08-17T19:20:24.957 に答える
23

UNIX バリアントでは、プロセスははるかに軽量です。Windows プロセスは重く、起動に時間がかかります。スレッドは、Windows でマルチプロセッシングを行うための推奨される方法です。

于 2009-08-17T19:13:25.203 に答える
5

Windows でプロセスを作成すると、Linux よりもコストがかかると言われています。サイト内を検索すると、いくつかの情報が見つかります。簡単に見つけたがこちら。

于 2009-08-17T19:12:49.527 に答える
2

プールを開始するだけでも時間がかかります。プールを開いたままにして多くの異なるプロセスに再利用し、メソッド呼び出し (通常は map.async を使用) を介して参照を渡すことができる場合、「現実世界」のプログラムで見つけた後、Linux では数パーセント節約できますが、Windows では多くの場合、所要時間を半分にすることができます。私の特定の問題では Linux の方が常に高速ですが、Windows でもマルチプロセッシングの利点が得られます。

于 2014-11-07T19:43:23.287 に答える
1

現在、counter() 関数は状態をあまり変更していません。メモリの多くのページを変更するように counter() を変更してみてください。次に、CPU バウンド ループを実行します。Linux と Windows の間にまだ大きな違いがあるかどうかを確認してください。

現在、python 2.6 を実行していないため、自分で試すことはできません。

于 2009-08-17T19:40:26.100 に答える