Грязное распараллеливание программы на Python

#python #numpy #scipy #scikit-image

#python #numpy #scipy #scikit-изображение

Вопрос:

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

 for file in files:
  codes[file] = my_function(file)
return codes
 

Проблема в том, что этот процесс занимает около 20-30 минут и, похоже, использует только одно ядро процессора. Я ищу быстрый и грязный способ запустить это на большем количестве ядер, возможно, разделив список на две части. Я много читал о Python и его проблемах / решениях, но я не могу понять, что делать дальше. Как мне это сделать?

К ВАШЕМУ сведению, использование Python 2.7 на Macbook Pro 2009 года (Core 2 Duo) с Numpy Scipy Scikit-изображение и OpenCV.

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

1. Если вы обрабатываете все изображения полностью независимо, создайте два сценария, оба обрабатывают набор из 1300 изображений. Запускайте сценарии один за другим, и тогда у вас должен быть один интерпретатор python, работающий на каждом ядре. (Но 1 для решения Патрика, которое действительно является чистым.)

2. Мы опишем это решение в руководстве пользователя scikit-image для следующего выпуска.

3. если вы хотите, чтобы это было действительно грязно, распараллеливайте в bash

Ответ №1:

Самый простой способ — с multiprocessing :

 from multiprocessing import Pool

with Pool() as p:
    all_codes = p.map(my_function, files)
return {f:code for code, f in zip(all_codes, files)}
 

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

1. Привет, Патрик! Большое спасибо, это выглядит великолепно! Два вопроса — не могли бы вы любезно объяснить последнюю строку и 2 нужно ли мне явно вызывать p.start(), чтобы запустить ее?

2. Последняя строка — это понимание словаря, чтобы возвращать данные в том же формате, который вы указали в своем вопросе (используя дескриптор файла в качестве ключа). Нет необходимости вызывать p.start() — использование p.map позволяет Python разумно распределять работу между процессами по мере завершения того, что они делают.

3. Это привело к ускорению более чем на 100%. Спасибо! 🙂

4. Один быстрый вопрос, ваш код работал не так, как ожидалось (ошибка атрибута в строке with); Я сделал это: p=Pool() all_codes = p.map(my_function, items) Они эквивалентны или я что-то пропустил?

5. У вас тоже есть import строка? И в области видимости есть что-то с именем items ?