【问题标题】:python script is slowly after use multiprocessingpython脚本在使用多处理后很慢
【发布时间】:2017-12-05 19:11:32
【问题描述】:

我已经创建了一个图像处理 python 函数。

我的系统有 4 个核心 + 4 个线程。

我想使用多处理来加速我的功能,但是任何时候使用多处理包我的功能都不是更快,而且慢了 1 分钟。 知道为什么吗?第一次使用多处理包。

主要功能:

if __name__ == '__main__':
    in_path="C:/Users/username/Desktop/in.tif"
    out_path="C:/Users/username/Desktop/out.tif"
    myfun(in_path, out_path)

时间=3.4 分钟

使用多处理地图:

if __name__ == '__main__':
    p = Pool(processes=4)
    in_path="C:/Users/username/Desktop/in.tif"
    out_path="C:/Users/username/Desktop/out.tif"
    result = p.map(myfun(in_path,out_path))

时间=4.4 分钟

if __name__ == '__main__':
    pool = multiprocessing.Pool(4)
    in_path="C:/Users/username/Desktop/in.tif"
    out_path="C:/Users/username/Desktop/out.tif"
    pool.apply_async(myfun, args=(in_path,out_path,))
    pool.close()
    pool.join()

时间=4.5 分钟

【问题讨论】:

  • 对,所以问题出在myfun(),你没有告诉我们。
  • @JohnZwinck 所以多处理仅适用于特定功能?
  • 为什么不给我们看代码让我们决定?

标签: python python-2.7 multiprocessing python-multiprocessing


【解决方案1】:

您在子进程中使用相同的参数执行相同的函数 - 这肯定会更慢,因为至少创建一个新进程会产生系统开销,然后是 Python 自己的高架。它创建了一个全新的解释器、堆栈、GIL……这需要时间。

在 POSIX 系统上,这个开销要快一些,因为它可以使用分叉和写时复制内存,但在 Windows 上,这基本上就像你从命令行调用 python -c "from your_script import myfun; myfun('C:/Users/username/Desktop/in.tif', 'C:/Users/username/Desktop/out.tif')" 一样,这需要相当长的时间.

只有当您有相当大的计算需求可以从您的函数中并行化时,您才会注意到多处理的好处。检查this answer 中的简单基准。

【讨论】:

  • 如果我再次使用你的建议,那么它会再次出现
  • @user27818 - 这不是展示一个示例,我向您解释了为什么将您的函数作为一个单独的进程运行需要更长的时间。总是这样,为了获得多处理的优势,您必须一次运行多个进程(最好进程数最多与您处理的可用 CPU 内核数相匹配)。我给出的另一个答案的链接通过multiprocessing.Pool.map()明确显示。
  • 你说我要像 myfunc1,myfunc2,myfunc3,myfunc3 这样将 myfunc 分解为 sub-myfunc 吗?
  • @user27818 - 不,我是说在不同的子进程中使用多组参数调用你的函数(你可以使用multiprocessing.Pool 为你管理它)。如果你只调用一个子进程,它的运行速度当然会比在你的主进程中运行所有东西要慢。
  • 我听不懂你
【解决方案2】:

multiprocessing.Pool.map() 不会自动使函数并行运行。所以Pool.map(my_function(single_input)) 不会让它运行得更快。事实上,它可能会使它变慢。

map() 的目的是如果您有多个输入,则允许您多次并行运行相同的函数。

如果你有:

in_paths = ['C:/Users/in1.tif', 'C:/Users/in2.tif', ... ]
out_paths = ['C:/Users/out1.tif', 'C:/Users/out2.tif', ... ]

那么你可以使用Pool.map()来加速你的程序,例如:

p = Pool(4)
results = p.map(my_function, zip(in_paths, out_paths))

但是由于您只有一个输入,因此您只需运行一次函数,因此没有区别。希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-14
    • 2013-12-21
    • 2019-07-01
    • 2018-09-22
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    • 2017-11-17
    相关资源
    最近更新 更多