joblib并行函数如何管理内存?

时间:2017-02-25 07:28:00

标签: python parallel-processing multiprocessing wand joblib

我正在编写一个将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如何管理每个并行实例的内存分配?

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

1 个答案:

答案 0 :(得分:3)

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

来自docs

  

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

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

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

简而言之:

  • 使用X核心,预计内存使用量增加X倍
    • 你无能为力
  • 如果你观察到比预期的线性消耗更多的内存消耗,那么似乎有些错误
  • 我不确定您拥有多少核心,但您可以尝试使用n_jobs=4来限制此核心
  • 这种IO重处理不是并行处理的理想选择
    • IO主宰计算!!!