多处理池 - 大多数工作人员已加载但仍处于空闲状态

Posted

技术标签:

【中文标题】多处理池 - 大多数工作人员已加载但仍处于空闲状态【英文标题】:Multiprocessing Pool - most workers are loaded but still idle 【发布时间】:2020-02-03 02:18:12 【问题描述】:

在 python 2.7 脚本中,第一个处理一大块 numpy 数组的多处理代码。这基本上是图像平面和笛卡尔(世界)平面之间的投影光线帧块。这部分名为poo1,工作正常。

在脚本的进一步部分,我尝试重现多处理代码以使用此投影光线帧块投影大量图像。

似乎只有 4 到 6 名工作人员在工作,但他们都已准备好填写数据。 pool2 创建了 worker,它们的内存使用增长缓慢,其中最多只有 6 个在使用 CPU。

截图

注意事项

从多处理函数获取没有输出返回,如果一个文件写入一个文件夹,则输出; 不用担心内存大小问题,半 TB 可用; 不用担心流程的顺序; worker 数量为物理 CPU 核心 - 1 = 27; 要分发的作业列表的长度 (paramsGeoRef) 可以是 1 到 250 行。

参数信息

Frameclock,海量ndarray,可以是GB A1 : ndarray,可以是数百 MB A2 : ndarray,可以是数百 MB B1:整数值 B2:整数值 文件名:字符串,名称 D1:字符串,路径 D2:字符串,路径 D3:字符串,路径 P1:小数组 P2:小数组

代码的简化如下所示

    def georef(paramsGeoRef):

        #Pseudo workflow
        """
        - unpack arguments, Frameclock, A1,A2, B1, B2, fileName, D1, D2, D3, P1, P2 <== paramsGeoRef
        - Loading tif image
        - Evergy convertion
            with function and P1, P2
        - Proportional projection of the image
            - Frameclock, A1, A2
        - Evergy convertion
            with function and P1, P2
        - Figure creation
        - Geotiff creation
        - export into file figure, geotiff and numpy file
        """
        return None

if __name__ == '__main__':

    paramsGeoRef = []
    for im in imgfiles:
        paramsGeoRef.append([Frameclock, A1, A2, B1, B2, fileName, D1 , D2 , D3 , P1 , P2])
    if flag_parallel:
        cpus = multiprocessing.cpu_count()
        cpus = cpus - 1
        pool2 = multiprocessing.Pool(processes=cpus)
        pool2.map(georef, paramsGeoRef)
        pool2.close()
        pool2.join()

我尝试了不同的方法,例如

解包之前的争论:

def star_georef(Frameclock, A1,A2, B1, B2, fileName, D1, D2, D3, P1, P2):
    return georef(*paramsGeoRef)

def georef(paramsGeoRef):
    #Pseudo workflow...
    return None

使用了另一种地图类型:

pool2.imap_unordered()

怎么了?为什么此方法适用于处理 numpy 数组,但不适用于此目的?需要处理块大小?

也许,我可能需要在工人有工作生成器后立即为他们提供食物?

【问题讨论】:

我怀疑瓶颈与将Frameclock GB 参数传递给每个进程有关。将其设为mmap 并传递它可能会更好,以避免涉及的开销(无论您投入多少硬件)。 我用 numpy 将 Frameclock、A1 和 A2 保存在 .npy 中。我将它加载到 georef 中。效率大幅提升!!!谢谢 很高兴听到 - 不客气。 问题:使用 memmap (np.memmap) 是否可以比诸如 .npy 之类的 pickle 更有效?特别是当您使用数百 MB ndarray 时。 是的,使用内存映射将有效地允许进程之间共享数据——我最初建议使用它的原因。 【参考方案1】:

遵循马蒂诺的建议,

我使用 numpy 以 .npy 格式保存 Frameclock、A1 和 A2 参数。然后我将 .npy 加载到并行化的 .npy 中。

如:

def georef(paramsGeoRef):

    #Pseudo workflow
    """
    - unpack arguments, Frameblock, A1,A2, B1, B2, fileName, D1, D2, D3, P1, P2 <== paramsGeoRef
    - load Frameblock from his .npy
    - load A1 from his .npy
    - load A2 from his .npy
    - Loading tif image
    - Evergy convertion
        with function and P1, P2
    - Proportional projection of the image
        - Frameclock, A1, A2
    - Evergy convertion
        with function and P1, P2
    - Figure creation
    - Geotiff creation
    - export into file figure, geotiff and numpy file
    """
    return None

即使保存和加载这些文件也能大大提高效率!所有工人都在工作。

【讨论】:

以上是关于多处理池 - 大多数工作人员已加载但仍处于空闲状态的主要内容,如果未能解决你的问题,请参考以下文章

xxx 的副本已从模块树中删除,但仍处于活动状态

线程池原理剖析

Java 多线程 - 空闲线程的状态

存在-db restxq 触发器:服务已删除但仍处于活动状态

线程池

Cartographer中的线程池操作