【问题标题】:ProcessPoolExecutor increase performance in non-intuitive wayProcessPoolExecutor 以非直观的方式提高性能
【发布时间】:2020-10-30 21:08:14
【问题描述】:

我有一个基本上是多线程的应用程序:线程 1 是计算,线程 2 是 GUI(Tkinter)。计算的一部分包括一个带有循环的函数。所以我决定在这里以这样的方式使用多处理:

def mpw1(idw_tree, mapsdata, inlines, xlines, x, y, dfattrs, calcplan, attrsdim, mdim):

    n_cores = os.cpu_count()
    flatcubec2 = np.zeros((attrsdim,mdim))

    with ProcessPoolExecutor(n_cores) as ex:
            args = ((i, calcplan, idw_tree, mapsdata, dfattrs, flatcubec2, inlines, xlines, n_cores) for i in range(n_cores))
            flatcubec2 = ex.map(circle, args)

    return flatcubec2

其中circle 只是一个计算函数(假设它在计数)。

但奇怪的是,尽可能设置n_cores 并不能让我获得最佳性能。这是一些信息:

8 核(最大)- 17 秒
6 核 - 14 秒
4 核 - 12 秒
3 核 - 14 秒
2 核 - 17 秒

究竟发生了什么?为什么使用最大的硬件不能获得最佳性能?我使用多线程的方式有问题吗?

【问题讨论】:

  • 由于您不接受当前的答案,您在寻找什么样的答案?您是否打算使用更多信息更新您的答案?根据您目前提供的信息,我认为很难给出更有用的答案。
  • 对不起,我的回答迟了,但问题已经解决。这种行为的原因是我使用了错误的命令 (multiprocessing.cpu_count()) 来设置要使用的进程数量,该命令返回的结果是应有的两倍,在 mp 中必须只使用物理 cpu,没有逻辑...
  • 很高兴听到您找到了解决方案。您可以将其发布为答案吗?其他用户(包括我)可能对细节感兴趣。如果您认为这是可用的最佳答案,您甚至可以接受自己的答案。提前致谢。

标签: python multiprocessing python-multiprocessing python-multithreading


【解决方案1】:

首先,由于您使用的是ProcessPoolExecutor,它是多处理,而不是多线程。由于全局解释器锁,多线程在 Python 中几乎没有性能提升。

其次,如果不查看实际代码,就很难解释应用程序的性能。多处理涉及相当多的开销,因此只有在您有相当多的处理工作要做(当然还有足够的可用内核来执行这些进程)时它才有用。

从您发布的结果看来,最多 4 个内核的工作负载被分配到可用内核上,并且获得了一些性能,但是当使用更多内核时,开销会增加到比获得的收益更昂贵的程度处理时间。

【讨论】:

  • 感谢您的回复,是的,您是对的,ProcessPoolExecutor 指的是多处理,但是,正如我之前所说,一般来说,我发布的代码是在一个全局线程中启动的(因为在这个线程之外是另一个带有 GUI 部分的线程,我更喜欢隐藏它)你所说的“一些开销”是什么意思,它如何解释为什么使用更多内核会导致性能下降,因为其他内核的负载会减少......
  • @АндрейСевостьянов,启动和停止进程也需要时间(我不确定您是在循环中执行此操作还是每个进程仅启动一次并运行 12-17 秒) .此外,根据访问的数据,当多个内核使用缓存时,缓存的效果可能不太理想。可能有很多原因,但如果不知道实际代码,我真的无法更详细地回答。您可以创建一个minimal reproducible example 并将其添加到您的问题中吗?当只执行计算线程而忽略 GUI 时,你能重现这个问题吗?这将为理解问题提供有用的信息。
【解决方案2】:

这种行为的原因是我使用了错误的命令 (multiprocessing.cpu_count()) 来设置要使用的进程数量,该命令返回的结果是应有的两倍,在 mp 中只需要使用物理cpu,没有逻辑 因此,当第四个“工人”(在我的情况下是物理 cpu 的最大值)之后性能开始下降时,这种行为可以通过以下事实来解释:多处理仅对物理 cpu 有效且可预测。为了获得物理 CPU 的数量,我只使用了:

psutil.cpu_count(logical = False)

【讨论】:

    猜你喜欢
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 2015-12-05
    • 2021-05-18
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多