4

「並列アプリケーションから最大のパフォーマンスを得たい場合は、コンピューターの CPU と同じ数のプロセスを作成し、各プロセスでいくつかの (いくつの?) スレッドを作成する必要がある」という話を聞いたことがあります。

本当ですか?

このイディオムを実装するコードを書きました。

import multiprocessing, threading

number_of_processes = multiprocessing.cpu_count()
number_of_threads_in_process = 25   # some constant


def one_thread():
    # very heavyweight function with lots of CPU/IO/network usage
    do_main_work()


def one_process():
    for _ in range(number_of_threads_in_process):
        t = threading.Thread(target=one_thread, args=())
        t.start()


for _ in range(number_of_processes):
    p = multiprocessing.Process(target=one_process, args=())
    p.start()

それが正しいか?私のdo_main_work関数は実際に並行して実行され、GIL の問題に直面することはありませんか?

ありがとうございました。

4

3 に答える 3

3

それはあなたが何をしているかに大きく依存します。

CPython では、一度に1 つのスレッドしか Python バイトコードを実行できないことに注意してください (GIL のため)。そのため、CPython スレッドの計算集約型の問題では、それほど役に立ちません。

並行して実行できる作業を分散させる 1 つの方法は、multiprocessing.Pool. デフォルトでは、これは CPU がコアを持っているより多くのプロセスを使用しません。より多くのプロセスを使用すると、有用な作業を完了するよりも、主にリソース (CPU、メモリ) をめぐって争うことになります。

ただし、複数のプロセッサを利用するには、プロセッサが実行する作業が必要です。つまり、問題を個別に並列に計算できる小さな断片に分割できない場合、多くの CPU コアはあまり役に立ちません。

さらに、すべての問題が、実行しなければならない計算量に拘束されるわけではありません。

コンピュータの RAM は、CPU よりもはるかに低速です。作業しているデータセットが CPU のキャッシュよりもはるかに大きい場合、RAM からデータを読み取り、結果を RAM に返すことが速度制限になる可能性があります。これは、メモリーバウンドと呼ばれます。

また、マシンのメモリに収まりきらないほど多くのデータを処理している場合、プログラムはディスクから大量の読み取りと書き込みを行うことになります。ディスクは RAM に比べて遅く、CPU に比べて非常に遅いため、プログラムはI/O バウンドになります。

于 2014-07-30T13:01:54.137 に答える