Windows および Linux での CPU バウンド作業に対する Python マルチプロセスとスレッドの比較 質問する

Windows および Linux での CPU バウンド作業に対する Python マルチプロセスとスレッドの比較 質問する

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

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

私のデュアルコア MacBook Pro でも同じ動作が見られます:

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

その後、Windows マシンで試してみたところ、まったく異なる結果が得られました。

ウィンドウズ (i7 920):
シリアル実行に 1043.000 ミリ秒かかりました
並列実行には 3237.000 ミリ秒かかりました
threadedrun は 2343.000 ミリ秒かかりました

どうして、マルチプロセス アプローチは Windows ではこんなに遅くなるのでしょうか?

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

#!/usr/bin/env python

マルチプロセッシングをインポートする
インポートスレッド
インポート時間

def print_timing(関数):
    defラッパー(*引数):
        t1 = 時間.時間()
        res = 関数(*引数)
        t2 = 時間.時間()
        '%s には %0.3f ミリ秒かかりました' と出力 % (func.func_name, (t2-t1)*1000.0)
        戻り値
    返品ラッパー


カウンタ()を定義します:
    i が xrange(1000000) の場合:
        合格

印刷タイミング
シリアル実行の定義(x):
    i が xrange(x) 内にある場合:
        カウンター()

印刷タイミング
def parallelrun(x):
    プロセスリスト = []
    i が xrange(x) 内にある場合:
        p = マルチプロセッシング.プロセス(ターゲット=カウンター)
        proclist.append(p)
        p.開始()

    proclist の i の場合:
        参加する()

印刷タイミング
スレッド実行の定義(x):
    スレッドリスト = []
    i が xrange(x) 内にある場合:
        t = スレッド.Thread(ターゲット=カウンター)
        スレッドリストに追加(t)
        t.開始()

    スレッドリスト内の i の場合:
        参加する()

main() を定義します:
    シリアルラン(50)
    並列実行(50)
    スレッドラン(50)

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

ベストアンサー1

マルチプロセッシングの 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

パラレルはまだ遅いですが、他のはゴムが燃えます。

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

@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

おすすめ記事