私は現在、プールを備えたPythonのマルチプロセッシングモジュールを使用して、関数を何百万回も同時に実行しています。マルチプロセッシングはうまく機能しますが、この関数は非常に軽量であるため、各コアの30%しか使用されず、Locking()中にのみスレッドが最大になります。私のスクリプトのプロファイルを見ると、確かにロックは最も費用がかかります。
各関数の実行が非常に短いことを考えると、関数にマッピングするたびにロックすることと関数を実行することの間のトレードオフは価値がありません(実際、シリアルで実行することでパフォーマンスが向上しています。15分並列化対4.5分シリアル)。
この関数は独立したファイルに書き込むため、呼び出しは完全に独立しています。同じ並列化されたPythonスクリプトを(異なる入力で)複数回実行/呼び出すことを「模倣」して、CPUをさらに活用することは可能ですか?
現在のコード:
pool = Pool(cpu_count(), initializer=tqdm.tqdm.set_lock, initargs=(Lock(),))
for _ in tqdm.tqdm(pool.imap_unordered(parallel_process, pubfiles, chunksize=70), total=nfiles, desc='Parsing files'):
pass
編集:
tqdmのロックとは関係がないことを確認するには、コードを次のように変更すると同じ問題が発生します。
pool = Pool(cpu_count())
for i in pool.imap_unordered(parallel_process, files, chunksize=70):
print(i)
私はしばらくの間コードのプロファイルを作成しましたが、最も高価なプロセスは一般にロック(?)/マルチプロセッシングに関連しているようです。実際の機能は、処理時間の最下部に非常に近いものです。
この問題はマルチプロセッシングとは何の関係もありませんでした。各呼び出しがファイルの読み取りとディスクへの書き込みを行っていたため、関数はIOバウンドであり、これは並列実行時のボトルネックでした。チャンク化して書き込まれるファイルの数を減らすと、このボトルネックが減り、上記のマルチプロセッシングコード(並列処理)は完全に正常に機能しました。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加