Ускорение выполнения программы на Python с использованием многопроцессорной обработки - PullRequest
0 голосов
/ 12 мая 2018

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

У меня есть папка с 100 000 изображений. У меня есть скрипт Python, который берет каждое изображение, выполняет некоторые операции над изображением и сохраняет результат в другой каталог.

Требуется 5 секунд для каждой операции с изображением.

У меня следующий вопрос -

Когда мой скрипт выполняется на одном изображении. Если я посмотрю на статистику процессора с помощью команды top, то увижу, что ни мой процессор, ни моя память не работают на 100% (это многоядерный процессор)

Более того, я могу обрабатывать больше изображений в минуту, просто запустив множество сценариев Python в разных оболочках.

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

Любые ресурсы / комментарии будут полезны.

Ответы [ 3 ]

0 голосов
/ 12 мая 2018

Операции ввода-вывода файлов открытия / чтения / записи - это те, которые приводят к простоям вашего процессора

при обработке изображения это обычно матричные умножения и занимает много ресурсов процессора и может выполняться параллельно на основе ядер процессора (дает или берет 2 * ядра)

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

Я предлагаю использовать образец рабочей очереди, описать здесь

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

имейте в виду, что для полного использования ядер процессора необходимо создать несколько потоков циклов событий, по одному (или двум) на ядро, потоки автоматически масштабируются (большинство ОС) на ядрах процессора

0 голосов
/ 15 мая 2018

Вы можете использовать binge (pip install binge) - это многопроцессорная оболочка общего назначения:

def image_worker(image_path, output_path):
    (load image, process, and save)
    return None

img_paths = ['./img1.png',
             './img2.png',
             ...
             './img100000.png']

from binge import B
result = B(worker, cores=4)(img_paths, '../otherfolder/')

где cores - сколько процессов будет использовано. Результатом будет список возвращаемых значений image_worker, то есть список Nones.

ср: разовая документация

0 голосов
/ 12 мая 2018

вы можете использовать библиотеку asyncio для одновременной обработки изображений. Вы просто определяете цикл обработки событий, регистрируете задачи в цикле обработки событий, и на этом все. Система решает, какой из них запустить дальше. Когда задача привязана к вводу / выводу (в вашем случае, сохраняя значение в каком-либо месте системы) или ожидая ответа откуда-либо, система выбирает другую задачу из цикла событий вместо ожидания и т. Д.

https://docs.python.org/3/library/asyncio.html

...