【问题标题】:How does joblib Parallel function manage the memory?joblib Parallel 函数如何管理内存?
【发布时间】:2017-02-25 07:28:00
【问题描述】:

我正在编写一个将 PDF 转换为 PNG 图像的函数,它看起来像这样:

import os
from wand.image import Image

def convert_pdf(filename, resolution):
    with Image(filename=filename, resolution=resolution) as img:
        pages_dir = os.path.join(os.path.dirname(filename), 'pages')
        page_filename = os.path.splitext(os.path.basename(filename))[0] + '.png'
        os.makedirs(pages_dir)
        img.save(filename=os.path.join(pages_dir, page_filename))

当我尝试并行化它时,内存在增长,我无法完成对 PDF 文件的处理:

def convert(dataset, resolution):
    Parallel(n_jobs=-1, max_nbytes=None)(
        delayed(convert_pdf)(filename, resolution) for filename in glob.iglob(dataset + '/**/*.pdf', recursive=True)
    )

当我串行调用函数时,内存保持不变。

joblib 如何管理每个并行实例的内存分配?

如何修改我的代码以使内存在并行运行时保持不变?

【问题讨论】:

    标签: python parallel-processing multiprocessing wand joblib


    【解决方案1】:

    Joblib 将使用序列化技术将数据传递给您的所有工作人员。当然内存会随着工人数量的增加而增长。

    来自docs

    默认情况下,池中的工作人员是真正的 Python 进程,当 n_jobs != 1 时,使用 Python 标准库的多处理模块派生。作为输入传递给 Parallel 调用的参数被序列化并在每个工作进程的内存中重新分配.

    没有办法并行处理 2 个文件而只有 1 个内存(如果你真的想要加速的话)!

    文档还提到了内存映射,这些映射通常用于数字数据以及当这些工作人员共享数据时(操作系统负责缓存)。这在这里无济于事,因为您的案例中没有共享数据。但是由于内存映射在缓存方面会自动保持内存友好,因此在这种情况下不应该发生基于内存的程序崩溃,但当然这个 IO 完成(与缓存相反)会降低性能。

    简而言之:

    • 使用 X 个内核,预计内存使用量增加 X 倍
      • 你无能为力
    • 如果您观察到比预期的线性消耗更多的内存消耗,那么似乎有问题
    • 我不确定您有多少核心,但您可以尝试使用 n_jobs=4 来限制这一点
    • 这种 IO 繁重的处理不是并行处理的自然候选者
      • IO 主导计算!!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-19
      • 1970-01-01
      • 2023-02-09
      • 1970-01-01
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      • 2013-05-28
      相关资源
      最近更新 更多