使用多处理加速python程序执行

时间:2018-05-12 12:59:58

标签: python multithreading unix multiprocessing distributed-computing

尝试更好地理解多处理以及如何将其用于以下场景。

我有一个包含100,000张图片的文件夹。我有一个python脚本,它接收每个图像,对图像执行一些操作并将结果存储到另一个目录中。

图像上的每个操作都需要5秒钟。

我的问题如下 -

当我的脚本在单个图像上执行时。如果我使用top命令查看cpu statistics,我可以看到我的cpu或内存都不是100%(这是一个多核处理器)

此外,我可以通过简单地在不同的shell中启动许多python脚本来每分钟处理更多图像。

以更快的方式执行此任务的pythonic方法是什么?如果图像数量增加,我如何水平缩放?

任何资源/评论都会有所帮助。

3 个答案:

答案 0 :(得分:0)

您可以使用asyncio库同时处理图像。您只需定义一个事件循环,将任务注册到事件循环中,这就是全部。系统决定下一个运行哪个。当一个任务被I / O绑定(在你的情况下,将值存储到系统中的某个地方),或等待来自某个地方的响应时,系统从事件循环中选择另一个任务而不是等待,依此类推。

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

答案 1 :(得分:0)

打开/读/写文件的I / O操作是导致cpu空闲的操作

处理图像时,它通常是一个矩阵乘法并占用大量的cpu资源,可以根据cpu内核并行完成(给出或取2 *个内核)

我的建议是根据任务使用不同的线程池,为了处理文件,你可以创建任意数量的线程,而不需要太多的性能降级,但是处理图像,即使用字节数组进行计算可以扩展到与cpu核心,你应该注意到性能降级

我建议使用worker-queue模式描述here

您还可以查看事件循环实现,由于其非阻塞性质可能会产生更好的结果,您可以找到示例here

请记住,要充分利用cpu核心,你应该创建多个事件循环线程,每个核心一个(或两个),线程在cpu核心上自动缩放(大多数os)

答案 2 :(得分:0)

您可以使用bingepip 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列表。

cf:binge documentation