我试图在Python中使用多进程加速一些代码,但我无法理解其中的一点。假设我有以下哑函数:
import time
from multiprocessing.pool import Pool
def foo(_):
for _ in range(100000000):
a = 3 当我不使用多处理(见下面的代码)在我的笔记本电脑(Intel-8核心cpu)上运行这段代码时,花费的时间大约是2.31秒。
t1 = time.time()
foo(1)
print(f"Without multiprocessing {time.time() - t1}")相反,当我使用Python多处理库(请参阅下面的代码)运行这段代码时,花费的时间是~6.0秒。
pool = Pool(8)
t1 = time.time()
pool.map(foo, range(8))
print(f"Sample multiprocessing {time.time() - t1}")据我所知,在使用多处理时,主要是由于需要生成新进程和复制内存状态而造成的时间开销。然而,这个操作应该在刚开始的时候只执行一次,不应该太大。
所以我在这里错过了什么?我的推理有什么问题吗?
编辑:,我认为在我的问题上讲得更清楚些更好。我在这里所期望的是,多处理代码比顺序代码稍微慢一些。的确,我没有将整个工作分散在8个核上,但我使用8个核并行完成相同的工作(因此,在理想的世界中,处理时间应该大致保持不变)。考虑到产生新进程的开销,我预计总时间会增加一些(不太大)百分比,但不会增加2.60倍,因为我到了这里。
发布于 2020-05-19 21:24:47
嗯,多重处理不可能使这个过程更快:您不是将工作划分为8个进程,而是要求8个进程中的每个进程完成整个任务。每个进程至少要花费您的代码一次而不使用多处理的时间。
因此,如果多处理根本没有帮助,您可能会期望它花费大约8倍的时间(它正在做8倍的工作!)当你的单处理器运行时。但是你说它不是用2.31 *8 ~= 18.5秒,而是“只有”大约6。所以你比3加速比的一倍更好。
为什么不超过这个呢?从这里猜不出来。这将取决于您的机器有多少物理核心,以及您同时运行的其他东西有多少。对于这个特定的功能,每个进程都是100%的CPU绑定,所以“逻辑”核的数量几乎是不相关的-处理器超线程几乎没有机会提供帮助。所以我猜你有四个物理核心。
在我的盒子上
我的盒子上有8个逻辑核,但只有4个物理核,所以我的盒子上的示例定时非常安静:
Without multiprocessing 2.468580484390259
Sample multiprocessing 4.78624415397644如前所述,这一切都没有让我感到惊讶。事实上,对于这个程序如何有效地消耗了机器的真正容量,我感到有点惊讶(但令人愉快)。
发布于 2020-05-19 23:16:40
@TimPeters已经回答说,您实际上只是在8个池子进程中运行了8次作业,所以运行速度更慢,而不是更快。
这回答了问题,但没有真正回答你真正的潜在问题是什么。从您对此结果的惊讶中可以清楚地看到,您预期单个作业将以某种方式自动拆分,并在8个池进程中运行。这不是它的工作方式。你必须自己动手/告诉它如何把工作分开。
不同类型的工作需要以不同的方式细分,但是要继续使用您的示例,您可以这样做:
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()其结果是:
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,但一些好处是失去了开销。如果工作时间更长,这看起来会更有用。
https://stackoverflow.com/questions/61900904
复制相似问题