Многопроцессорная обработка словаря в python

#python #multiprocessing

#python #многопроцессорная обработка

Вопрос:

У меня есть два словаря данных, и я создал функцию, которая действует как механизм правил для анализа записей в каждом словаре и выполняет действия на основе определенных установленных мной показателей (если это помогает, каждая запись в словаре является узлом в графе, и если правила совпадают, я создаю ребра между ними).

Вот код, который я использую (это цикл for, который передает части словаря в функцию rules . Я переработал свой код в соответствии с учебным пособием, которое я прочитал):

 jobs = []
    def loadGraph(dayCurrent, day2Previous):
        for dayCurrentCount  in graph[dayCurrent]:
            dayCurrentValue = graph[dayCurrent][dayCurrentCount]
            for day1Count  in graph[day2Previous]:
                day1Value = graph[day2Previous][day1Count]
                #rules(day1Count, day1Value, dayCurrentCount, dayCurrentValue, dayCurrent, day2Previous)
            p = multiprocessing.Process(target=rules, args=(day1Count, day1Value, dayCurrentCount, dayCurrentValue, dayCurrent, day2Previous))
            jobs.append(p)
            p.start()
            print ' in rules engine for day', dayCurrentCount, ' and we are about ', ((len(graph[dayCurrent])-dayCurrentCount)/float(len(graph[dayCurrent])))
  

Данные, которые я изучаю, могут быть довольно большими (могут, потому что они генерируются случайным образом). Я думаю, что на каждый день приходится около 50 000 записей. Поскольку на этом этапе тратится большая часть времени, мне было интересно, могу ли я использовать имеющиеся у меня 8 ядер, чтобы ускорить обработку.

Поскольку каждая словарная запись сравнивается со словарной записью предыдущего дня, я подумал, что процессы могут быть разделены этим, но мой приведенный выше код работает медленнее, чем при обычном использовании. Я думаю, это связано с тем, что он создает новый процесс для каждой записи, которую он выполняет.

Есть ли способ ускорить это и использовать все мои процессоры? Моя проблема в том, что я не хочу передавать весь словарь, потому что тогда одно ядро будет его обрабатывать, я бы предпочел, чтобы процесс был разделен на каждый процессор или таким образом, чтобы я максимально использовал все свободные процессоры для этого.

Я совершенно новичок в многопроцессорной обработке, поэтому я уверен, что мне не хватает чего-то простого. Любые советы / предложения или материалы для чтения были бы замечательными!

Ответ №1:

Что я делал в прошлом, так это создание «рабочего класса», который обрабатывает записи данных. Затем я раскручу X количество потоков, каждый из которых запускает копию рабочего класса. Каждый элемент в наборе данных помещается в очередь, которую просматривают рабочие потоки. Когда в очереди больше нет элементов, потоки замедляются.

Используя этот метод, я смог обработать более 10 000 элементов данных с использованием 5 потоков примерно за 3 секунды. Когда приложение было только однопоточным, это заняло бы значительно больше времени.

Проверьте: http://docs.python.org/library/queue.html

Ответ №2:

Я бы рекомендовал изучить реализации MapReduce в Python. Вот один из них: http://www.google.com/search?sourceid=chromeamp;ie=UTF-8amp;q=mapreduce python . Кроме того, взгляните на пакет python под названием Celery: http://celeryproject.org /. С помощью celery вы можете распределять свои вычисления не только между ядрами на одной машине, но и на ферме серверов (кластере). Вы платите за эту гибкость с более сложной настройкой / обслуживанием.

Комментарии:

1. Спасибо. На самом деле у меня есть общий процесс, запущенный в hadoop (и hbase). Это нормально, но я добавляю больше функций и хотел воспользоваться преимуществами большего количества ядер. Сельдерей выглядит интересно, и я посмотрю.