首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么多处理在这里比较慢?

为什么多处理在这里比较慢?
EN

Stack Overflow用户
提问于 2020-05-19 21:16:11
回答 2查看 1.5K关注 0票数 6

我试图在Python中使用多进程加速一些代码,但我无法理解其中的一点。假设我有以下哑函数:

代码语言:javascript
复制
import time
from multiprocessing.pool import Pool

def foo(_):
    for _ in range(100000000):
        a = 3 

当我不使用多处理(见下面的代码)在我的笔记本电脑(Intel-8核心cpu)上运行这段代码时,花费的时间大约是2.31秒。

代码语言:javascript
复制
t1 = time.time()
foo(1)
print(f"Without multiprocessing {time.time() - t1}")

相反,当我使用Python多处理库(请参阅下面的代码)运行这段代码时,花费的时间是~6.0秒。

代码语言:javascript
复制
pool = Pool(8)
t1 = time.time()
pool.map(foo, range(8))
print(f"Sample multiprocessing {time.time() - t1}")

据我所知,在使用多处理时,主要是由于需要生成新进程和复制内存状态而造成的时间开销。然而,这个操作应该在刚开始的时候只执行一次,不应该太大。

所以我在这里错过了什么?我的推理有什么问题吗?

编辑:,我认为在我的问题上讲得更清楚些更好。我在这里所期望的是,多处理代码比顺序代码稍微慢一些。的确,我没有将整个工作分散在8个核上,但我使用8个核并行完成相同的工作(因此,在理想的世界中,处理时间应该大致保持不变)。考虑到产生新进程的开销,我预计总时间会增加一些(不太大)百分比,但不会增加2.60倍,因为我到了这里。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-19 21:24:47

嗯,多重处理不可能使这个过程更快:您不是将工作划分为8个进程,而是要求8个进程中的每个进程完成整个任务。每个进程至少要花费您的代码一次而不使用多处理的时间。

因此,如果多处理根本没有帮助,您可能会期望它花费大约8倍的时间(它正在做8倍的工作!)当你的单处理器运行时。但是你说它不是用2.31 *8 ~= 18.5秒,而是“只有”大约6。所以你比3加速比的一倍更好。

为什么不超过这个呢?从这里猜不出来。这将取决于您的机器有多少物理核心,以及您同时运行的其他东西有多少。对于这个特定的功能,每个进程都是100%的CPU绑定,所以“逻辑”核的数量几乎是不相关的-处理器超线程几乎没有机会提供帮助。所以我猜你有四个物理核心。

在我的盒子上

我的盒子上有8个逻辑核,但只有4个物理核,所以我的盒子上的示例定时非常安静:

代码语言:javascript
复制
Without multiprocessing 2.468580484390259
Sample multiprocessing 4.78624415397644

如前所述,这一切都没有让我感到惊讶。事实上,对于这个程序如何有效地消耗了机器的真正容量,我感到有点惊讶(但令人愉快)。

票数 9
EN

Stack Overflow用户

发布于 2020-05-19 23:16:40

@TimPeters已经回答说,您实际上只是在8个池子进程中运行了8次作业,所以运行速度更慢,而不是更快。

这回答了问题,但没有真正回答你真正的潜在问题是什么。从您对此结果的惊讶中可以清楚地看到,您预期单个作业将以某种方式自动拆分,并在8个池进程中运行。这不是它的工作方式。你必须自己动手/告诉它如何把工作分开。

不同类型的工作需要以不同的方式细分,但是要继续使用您的示例,您可以这样做:

代码语言:javascript
复制
import time
from multiprocessing.pool import Pool

def foo(_):
    for _ in range(100000000):
        a = 3 

def foo2(job_desc):
    start, stop = job_desc
    print(f"{start}, {stop}")

    for _ in range(start, stop):    
        a = 3 

def main():
    t1 = time.time()
    foo(1)
    print(f"Without multiprocessing {time.time() - t1}")

    pool_size = 8
    pool = Pool(pool_size)

    t1 = time.time()

    top_num = 100000000
    size = top_num // pool_size
    job_desc_list = [[size * j, size * (j+1)] for j in range(pool_size)]
    # this is in case the the upper bound is not a multiple of pool_size
    job_desc_list[-1][-1] = top_num

    pool.map(foo2, job_desc_list)
    print(f"Sample multiprocessing {time.time() - t1}")


if __name__ == "__main__":
    main()

其结果是:

代码语言:javascript
复制
Without multiprocessing 3.080709171295166
0, 12500000
12500000, 25000000
25000000, 37500000
37500000, 50000000
50000000, 62500000
62500000, 75000000
75000000, 87500000
87500000, 100000000
Sample multiprocessing 1.5312283039093018

如图所示,将工作分开确实可以减少花费的时间。加速将取决于CPU的数量。在与CPU绑定的作业中,您应该尝试将池大小限制在CPU数量上。我的笔记本电脑有更多的CPU,但一些好处是失去了开销。如果工作时间更长,这看起来会更有用。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61900904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档