簡単な例で並列ループを実行しようとしています。
何が悪いのですか?
from joblib import Parallel, delayed
import multiprocessing
def processInput(i):
return i * i
if __name__ == '__main__':
# what are your inputs, and what operation do you want to
# perform on each input. For example...
inputs = range(1000000)
num_cores = multiprocessing.cpu_count()
results = Parallel(n_jobs=4)(delayed(processInput)(i) for i in inputs)
print(results)
コードの問題は、Python 3のWindows環境で実行すると、並列ジョブを実行するためにpythonのnum_cores
インスタンスを開きますが、プロセッサのアクティビティは14%ではなく100%である必要があるため(i7-8ロジックコア)、これは当てはまりません。
追加のインスタンスが何も実行しないのはなぜですか?
機能するマルチプロセッシングコードを提供するというリクエストを続けて、 pool_map を使用することをお勧めします(遅延機能が重要でない場合)、python3で作業している場合の例を紹介しますスターマップを使用できることに言及する価値があります。返される結果の順序が入力の順序に対応する必要がない場合は、map_sync/starmap_asyncを使用できることにも言及する価値があります。
import multiprocessing as mp
def processInput(i):
return i * i
if __name__ == '__main__':
# what are your inputs, and what operation do you want to
# perform on each input. For example...
inputs = range(1000000)
# removing processes argument makes the code run on all available cores
pool = mp.Pool(processes=4)
results = pool.map(processInput, inputs)
print(results)
Windowsでは、マルチプロセッシングモジュールは 'spawn'メソッドを使用して複数のpythonインタープリタープロセスを起動します。これは比較的低速です。Parallelはコードの実行について賢く試みます。特に、バッチの実行に約0.5秒かかるようにバッチサイズを調整します( https://pythonhosted.org/joblib/parallel.html のbatch_size引数を参照)。
processInput()
関数は非常に高速で実行されるため、複数のpythonインタープリターを起動してコードを並列に実行するよりも、1つのプロセッサーでジョブを順次実行する方が高速であるとParallelが判断します。
サンプルを複数のコアで強制的に実行する場合は、batch_sizeを1000に設定するか、processInput()
をより複雑にして実行時間が長くなるようにします。
編集:使用中の複数のプロセスを表示するウィンドウでの作業例(Windows 7を使用しています):
from joblib import Parallel, delayed
from os import getpid
def modfib(n):
# print the process id to see that multiple processes are used, and
# re-used during the job.
if n%400 == 0:
print(getpid(), n)
# fibonacci sequence mod 1000000
a,b = 0,1
for i in range(n):
a,b = b,(a+b)%1000000
return b
if __name__ == "__main__":
Parallel(n_jobs=-1, verbose=5)(delayed(modfib)(j) for j in range(1000, 4000))