Распараллеливание программы python3 с огромными сложными объектами

вступление

У меня есть довольно сложная программа на Python (скажем, более 5000 строк), написанная с помощью Python 3.6. Эта программа анализирует огромный набор данных из более чем 5000 файлов, обрабатывает их, создавая внутреннее представление набора данных, а затем создает статистику. Поскольку мне нужно протестировать модель, мне нужно сохранить представление набора данных, и сейчас я делаю это, используя сериализацию через dill (в представлении есть объекты, которые pickle не поддерживает). Сериализация всего набора данных без сжатия занимает около 1 ГБ.

Эта проблема

Теперь я хотел бы ускорить вычисления за счет распараллеливания. Идеальным способом будет многопоточность, но GIL запрещает это. Модуль multiprocessingmultiprocess, который также dill совместим) использует сериализацию для обмена сложными объектами между процессами, так что, в лучшем случае, который мне удалось изобрести, распараллеливание не влияет на производительность по времени из-за огромного размера набора данных.

Вопрос

Как лучше всего справиться с этой ситуацией?

Я знаю о posh, но похоже, что он совместим только с x86, ray но он также использует сериализацию, gilectomy (версия python без gil), но я не могу заставить его распараллеливать потоки и Jython, у которого нет GIL, но нет совместим с python 3.x.

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


person fortea    schedule 11.02.2018    source источник
comment
Вам нужно, чтобы весь набор данных был доступен для всех процессоров? Это что-то, что можно было бы поместить в общую память Array (или какую-либо другую форму объекта общей памяти из multiprocess)?   -  person Mike McKerns    schedule 13.02.2018
comment
Насколько я понимаю, многопроцессорность (и многопроцессорность, поскольку их интерфейсы совместимы) может управлять только ctypes в общей памяти. Представление набора данных - это List[Tuple(String, List[StreamReduction])], где StreamReduction - объект Python, созданный мной и составленный из других созданных мной объектов, а последние, в свою очередь, состоят из music21 объектов, которые еще более сложны. Так что очень трудно перевести мои StreamReduction на типы C, даже если это теоретически возможно. Да, мне нужно сравнить каждый StreamReduction со всем набором данных, который представляет собой O(n^2).   -  person fortea    schedule 13.02.2018
comment
Да, все объекты типа C должны работать с _1 _..., но если у вас есть собственный класс ... хм, тогда я не уверен. Итак, ой, если вам нужно сравнить со всем набором данных, это плохая ситуация. Совершенно вне моей головы ... как насчет использования параллельной обработки с nogil в cython или чего-то подобного? Это потребует серьезного переписывания, но, возможно, в этом случае вам придется это сделать.   -  person Mike McKerns    schedule 13.02.2018
comment
Да, nogil и cython могут быть случайными, но мне понадобится оболочка для преобразования объектов Python в структуры C, потому что в блоках no gil могут быть затронуты только данные C   -  person fortea    schedule 13.02.2018
comment
Я обнаружил, что укроп действительно все тормозит. Возможно, решение этой проблемы может помочь ...   -  person fortea    schedule 13.02.2018
comment
Я думаю, что несмотря ни на что, травление будет медленнее, чем при использовании общей памяти. В dill есть несколько вещей, которые позволяют использовать более мелкие огурцы - например, dill.settings['byref'] = True, который позволяет dill мариновать классы и тому подобное по ссылке - однако другим потенциальным подходом было бы добавление метода reduce или reduce_ex к вашему классу, который направляет dill на выгрузите только то состояние, которое необходимо для сравнения.   -  person Mike McKerns    schedule 13.02.2018
comment
да, я только что обнаружил, что основная библиотека, которую я использую, имеет правильный способ сериализации объектов. Я думаю, что __reduce__ может помочь. Но главная проблема здесь - разделяемая память. Я думаю, прямого решения не существует. Я был энтузиастом Python, но это меня очень разочаровало   -  person fortea    schedule 13.02.2018
comment
Что ж, если вы думаете, что получили удовлетворительный ответ, тогда вам следует ответить на свой вопрос.   -  person Mike McKerns    schedule 13.02.2018


Ответы (1)


Лучшее решение, которое я нашел, - это изменить dill на специальный модуль травления, основанный на стандарте pickle. См. Здесь: Пользовательская процедура травления Python 3.6

person fortea    schedule 14.02.2018