【问题标题】:Speeding up python program execution using multiprocessing使用多处理加速 python 程序执行
【发布时间】:2018-05-12 12:59:58
【问题描述】:

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

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

对图像的每个操作需要 5 秒。

我的问题如下——

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

此外,我只需在不同的 shell 中启动许多 python 脚本,就能每分钟处理更多的图像。

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

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

【问题讨论】:

标签: python multithreading unix multiprocessing distributed-computing


【解决方案1】:

您可以使用asyncio 库来同时处理图像。您只需定义一个事件循环,将任务注册到事件循环中,仅此而已。系统决定接下来运行哪一个。当任务受 I/O 限制(在您的情况下,将值存储到系统内的某处)或等待某处的响应时,系统会从事件循环中选择另一个任务而不是等待,依此类推。

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

【讨论】:

    【解决方案2】:

    打开/读取/写入文件的 I/O 操作是导致您的 CPU 空闲的操作

    在处理图像时,它通常是矩阵乘法并占用大量 cpu 资源,并且可以基于 cpu 核心并行完成(给予或占用 2*cores)

    我的建议是根据任务使用不同的线程池,为了处理文件,您可以创建任意数量的线程而不会降低性能,但是处理图像(即使用字节数组进行计算)可以扩展至cpu cores,在上面你应该注意到性能下降

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

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

    记住要充分利用 cpu 核心,您应该创建多个事件循环线程,每个核心一个(或两个),线程在 cpu 核心上自动扩展(大多数操作系统)

    【讨论】:

      【解决方案3】:

      您可以使用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 的返回值列表,即 None 列表。

      cf:binge documentation

      【讨论】:

        猜你喜欢
        • 2014-10-25
        • 1970-01-01
        • 1970-01-01
        • 2021-01-06
        • 2022-01-27
        • 2017-01-02
        • 1970-01-01
        • 2020-05-24
        • 1970-01-01
        相关资源
        最近更新 更多