すべてのサブフォルダ内の同じパス構造と同じファイルを持つ2つのフォルダを比較したいと思います。フォルダはかなり大きく、サイズは約80GB、ファイル番号は8000です。Python Multiprocessing imap chunksize
2つのトップディレクトリの下にある対応するファイルペアのmd5チェックサム値が同じであることを確認したいと思います。私は、2つのディレクトリの下にあるすべてのファイルを検索し、ファイルサイズに従ってソートし、2つのリストに格納する単純なツリーDFS関数を作成しました。
リストを繰り返してみると、すべての比較を行うのに非常に時間がかかり、CPU使用率も低くなっています。
私はマルチプロセッシングモジュールがこの場合に適していると思います。
from multiprocessing import Pool, cpu_count
import hashlib
def calc_md5(item):
m = hashlib.md5()
with open(item, 'rb') as f:
for chunk in iter(lambda: f.read(4096), b""):
m.update(chunk)
return m.hexdigest()
def worker(args):
a, b = args
return calc_md5(a) == calc_md5(b)
def multi_compare(queue_a, queue_b, thread):
pool = Pool(processes = cpu_count() - 1)
# Task iterable
task = zip(queue_a, queue_b)
# Multiprocessing
for retval in pool.imap_unordered(worker, task, chunksize = 5):
if not retval:
print "Bad Detected"
ここqueue_a
とqueue_bは、ファイルサイズに応じてソートと比較するファイルのパスです:これは、マルチプロセッシングのための私の実装です。私はこのマルチプロセッシング手法の中でより高いCPU使用率とより良い性能を期待していますが、そうでないようです。シンプルなシーケンシャル・イテレーションには約3200秒かかりますが、マルチプロセッシング・メソッドは約4600秒かかります。
なぜこれが当てはまるのですか?これはマルチプロセッシングを使う良い点ですか?私のコードでこの悪いパフォーマンスのボトルネックは何ですか?それを改善する方法はありますか?
: 私は腸の感情に応じてチャンクサイズを設定しました。私はそれをスレッド番号によって分けられたqueue_aまたはqueue_bの長さに変更することができ、queue_a [0 :: thread]またはqueue_b [0 :: thread]要素を含む最初の1/4のようにタスクキューを並べ替えることができます。これは、同じサイズのタスクをすべてのスレッドに送り、すべてのスレッドを常にビジー状態に保ちます。私はこれが別のパフォーマンスを得る良い方法であるかどうかわからないし、私はまだこれについてテストしています。
: 上記の編集でのテストには4000秒かかります。 Chunksize = 5より少し良い。シリアルメソッドよりもさらに悪い。 このマルチプロセッシングプログラムのボトルネックをどうやって判断することができますか?
ありがとうございました!
ファイルはHDDにありますか?遅いシークのため、ほとんどのHDDはマルチスレッドの読み込みに悪いです。 – robyschek
@robyschekはい、私はHDDのPCにいると思います。私はSSDを使ってそれを試してみる。ありがとう! – yc2986