首页 > 解决方案 > GCP 上的多线程 Python 脚本中的 IO 速度突然下降

问题描述

我正在运行一个 Python 脚本来加载图像,以某种方式预处理图像,并将图像保存回缓存目录。大约有 50 万张图像。我们的用例运行时间太长,所以我添加了多线程。我们在 GCP Compute Engine 虚拟机实例上运行,原始图像位于 HDD 上,预处理后的图像保存到 SSD。

当使用 8 个 vCPU 和 12 个线程时,它在前 30 秒左右每秒处理大约 30-40 个图像。惊人的速度,完全适用于我们的用例。然后在 30 秒后,它突然下降到每秒 1 张图像左右,这是不可接受的。减速基本上是瞬间发生的,并且在几个小时内保持一致的每秒 1 张图像。我需要重新启动实例以再次获得更高的速度,尽管它总是变慢。重新启动 Python 脚本仍然会从一开始每秒生成 1 张图像。

当我将最大线程数限制为 4 个甚至 1 个线程时,它会做类似的事情。在单个工作人员的情况下,它以每秒 5 个图像的速度运行了大约 3 分钟,然后减速到每秒 1 个图像。所以这似乎是某种类型的速率限制/资源耗尽/配额限制。

什么可能导致这个问题?我该如何解决这个问题?

这是一个显示用法的代码示例:

import concurrent
import io
import pandas as pd


df = pd.DataFrame(...)

with concurrent.futures.ThreadPoolExecutor(max_workers=12) as pool:

    pool.map(preprocess_row,
             df['raw_path'],
             df['cache_path'],
             chunksize=1)
    )


def preprocess_row(raw_path, cache_path):
    
    img = io.imread(raw_path)
    img = ...                  # Arbitrary preprocessing

    io.imsave(cache_path, img)

使用 ProcessPoolExecutor 会导致同样的速度降低到每秒 1 个图像:

with concurrent.futures.ProcessPoolExecutor(max_workers=8) as pool:
    ...

标签: pythonmultithreadingimage-processingconcurrencyconcurrent.futures

解决方案


推荐阅读