Я хотел бы сравнить две папки с одинаковой структурой пути и одинаковыми файлами во всех подпапках. Папка довольно большая с размером около 80 ГБ и номерами файлов 8000.Python Multiprocessing imap chunksize
Я хотел бы убедиться, что все соответствующие пары файлов в двух верхних каталогах имеют одно и то же значение контрольной суммы md5. Я написал простую функцию дерева DFS, которая ищет все файлы в двух каталогах, сортирует их в соответствии с размерами файлов, сохраняя их в двух списках.
Когда я перебирал списки, мне было очень много времени, чтобы выполнить все сравнение, а также скорость использования ЦП была низкой.
Я думаю, что многопроцессорный модуль является чем-то хорошим для этого случая. Это моя реализация для многопроцессорной:
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 являются путями для Меряться файла, отсортированных по размеру файла. Я ожидаю более высокую загрузку процессора и лучшую производительность из этих многопроцессорных методов, но, похоже, это не так. Хотя простая последовательная итерация занимает около 3200 секунд, метод многопроцессорности занимает около 4600 секунд.
Мне интересно, почему это так? Это хороший момент для многопроцессорности? Что является узким местом этой плохой производительности в моем коде? Есть ли способ его улучшить?
Редактировать: Я установил chunksize в соответствии с моим чувством кишки. Думаю, я могу изменить его на длину queue_a или queue_b, разделенную номером потока, и отсортировать очередь задач как первую 1/4 из нее, содержащую элементы queue_a [0 :: thread] или queue_b [0 :: thread] и наоборот , Это будет поддерживать одинаковый размер задач для всего потока и постоянно поддерживать весь поток. Я не знаю, является ли это хорошим способом получить дополнительную производительность, и я все еще тестирую это.
Редактировать: Тест в приведенном выше редактировании занимает 4000 секунд. Чуть лучше, чем chunksize = 5. Еще хуже, чем серийный метод. Итак, я хотел бы спросить, как определить узкое место этой многопроцессорной программы.
Спасибо!
Ваши файлы на жестком диске? Большинство жестких дисков плохо в многопоточном чтении из-за медленного поиска. – robyschek
@robyschek Да, я думаю, что я на HDD-ПК. Я проверю его с помощью SSD и посмотрю. Благодаря! – yc2986